Вопрос по – Должен ли я изменить соглашение об именах для моих модульных тестов?

11

В настоящее время я использую простое соглашение для моих модульных тестов. Если у меня есть класс с именем «EmployeeReader», я создаю тестовый класс с именем «EmployeeReader.Tests». Затем я создаю все тесты для класса в классе тестов с такими именами, как:

Reading_Valid_Employee_Data_Correctly_Generates_Employee_Object Reading_Missing_Employee_Data_Throws_Invalid_Employee_ID_Exception

и так далее.

Я недавно читал одругой тип соглашения об именах используется в BDD. Мне нравится удобочитаемость этого наименования, в результате чего список тестов выглядит примерно так:

When_Reading_Valid_Employee (fixture) Employee_Object_Is_Generated (method) Employee_Has_Correct_ID (method) When_Reading_Missing_Employee (fixture) An_Invalid_Employee_ID_Exception_Is_Thrown (method)

и так далее.

Кто-нибудь использовал оба стиля именования? Можете ли вы дать какие-либо советы, преимущества, недостатки, ошибки и т. Д., Чтобы помочь мне принять решение о переходе на следующий проект или нет?

Ваш Ответ

7   ответов
0

EmployeeReaderTestCase и вызова методов (), какhttp://xunitpatterns.com/Organization.html а такжеhttp://xunitpatterns.com/Organization.html#Test%20Naming%20Conventions

3

а не одного для каждого класса) имеет то преимущество, что вы можете использовать разные логики SetUp и TearDown для каждой задачи, что упрощает ваши отдельные методы тестирования и делает их более читабельными.

Вам не нужно соглашаться на один или другой в качестве стандарта. Мы используем смесь обоих, в зависимости от того, сколько разных «заданий» мы должны проверить для каждого класса.

6

functionName_shouldDoThis_whenThisIsTheSituation

Например, это могли бы быть некоторые имена тестов для стека "pop" apos; функция

pop_shouldThrowEmptyStackException_whenTheStackIsEmpty

pop_shouldReturnTheObjectOnTheTopOfTheStack_whenThereIsAnObjectOnTheStack

1

и он действительно помогает описать, что должно делать ваше программное обеспечение. Я также использую вложенные классы для описания более подробного контекста.

По сути, тестовые классы - это контексты, которые могут быть вложенными, а методы - это утверждения в одну строку. Например,

public class MyClassSpecification
{
    protected MyClass instance = new MyClass();

    public class When_foobar_is_42 : MyClassSpecification 
    {
        public When_foobar_is_42() {
            this.instance.SetFoobar( 42 ); 
        }

        public class GetAnswer : When_foobar_is_42
        {
            private Int32 result;

            public GetAnswer() {
                this.result = this.GetAnswer();
            }

            public void should_return_42() {
                Assert.AreEqual( 42, result );
            }
        }
    }
}

что даст мне следующий результат в моем тесте бегуна:

MyClassSpecification+When_foobar_is_42+GetAnswer
    should_return_42
2

что второй вариант лучше, потому что он делает ваши юнит-тесты более читабельными для других, поскольку длинные строки делают код более сложным для чтения или затрудняют просмотр. Если вы все еще чувствуете двусмысленность относительно того, что делает тест, вы можете добавить комментарии, чтобы прояснить это.

1

которые вы описали в своем вопросе, а также несколько других ... Ваша первая альтернатива довольно проста и проста для понимания большинством людей. Мне лично больше нравится стиль BDD (ваш второй пример), потому что он изолирует различные контексты и группирует наблюдения в этих контекстах. Единственным недостатком является то, что он генерирует больше кода, поэтому начинать делать это будет немного громоздко, пока не увидите аккуратные тесты. Кроме того, если вы используете наследование для повторного использования настройки прибора, вам нужен тестовый прогон, который выводит цепочку наследования. Рассмотрим класс & quot; An_empty_stack & quot; и вы хотите использовать его повторно, чтобы затем сделать другой класс: & quot; When_five_is_pressed_on: An_empty_stack & quot; вы хотите это в качестве выходных данных, а не просто "When_five_is_pressed_on". Если ваш testrunner не поддерживает это, ваши тесты будут содержать избыточную информацию, например: & quot; When_five_is_phed_on_empty_stack: An_empty_stack & quot; просто чтобы сделать вывод приятным.

1

на которое вы ссылаетесь, заключается в том, что вы создаете тесты и поведенческие спецификации одновременно. Вы устанавливаете контекст, в котором происходит что-то, и что в действительности должно происходить в этом контексте. (По моему опыту, наблюдения / тест-методы часто начинаются с формата «должен _», поэтому вы получаете стандартный формат «When_the_invoicing_system_is_told_to_email_the_client», «should_initiate_connection_to_mail_server» ».

Есть инструменты, которые будут отражать ваши тестовые данные и выводить красиво отформатированный HTML-лист спецификации, удаляя подчеркивания. В итоге вы получите удобочитаемую документацию, которая синхронизируется с реальным кодом (при условии, что ваш тестовый охват будет высоким и точным).

В зависимости от истории / функции / подсистемы, над которой вы работаете, эти спецификации могут быть показаны и понятны заинтересованным сторонам, не являющимся программистами, для проверки и обратной связи, что лежит в основе гибкой и BDD в частности.

Похожие вопросы