модульный тест c # - соглашение об именах для перегруженных тестов методов - PullRequest
9 голосов
/ 14 апреля 2011

У меня есть несколько простых методов расширения в c #, против которых я пишу юнит-тесты.Один из методов расширения перегружен, поэтому я не могу придумать разумное соглашение об именах для модульных тестов.

Пример перегруженного метода:

public static class StringExtensions
{
    public static List<string> ToList(this string value, char delimiter)
    {
        return ToList(value, new[] { delimiter });
    }

    public static List<string> ToList(this string value, char[] delimiterSet) { .. }
}

Если я хочу написатьдва модульных теста, по одному на каждый метод, как бы вы назвали тесты?Обычно я использовал бы просто:

[TestMethod, TestCategory("Single Method Tests")]
public void ToListTest

Но с двумя методами с одним и тем же именем я изо всех сил пытаюсь найти хорошее соглашение.

[TestMethod, TestCategory("Single Method Tests")]
public void ToListTest

[TestMethod, TestCategory("Single Method Tests")]
public void ToListTestOverload

ужасно.

[TestMethod, TestCategory("Single Method Tests")]
public void ToListTestWithChar

[TestMethod, TestCategory("Single Method Tests")]
public void ToListTestWithCharArray

лучше по типу параметра, но все же довольно ужасно.

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

Как бы вы подошли к этому?

Ответы [ 3 ]

14 голосов
/ 14 апреля 2011

Рой Ошеров в своей книге «Искусство модульного тестирования» рекомендует использовать соглашения о присвоении имен, основанные на поведении, которое вы пытаетесь протестировать, и не обязательно иметь однозначное соответствие между методами производства и методами тестирования. Итак, в качестве простого примера, предположим, что у меня есть класс Stack, например:

public class Stack
{
    public void Push(int value);
    public int Pop();
    public bool IsEmpty();
}

Один из способов написания тестов - три метода тестирования:

[TestMethod]
public void PushTest

[TestMethod]
public void PopTest

[TestMethod]
public void IsEmptyTest

Однако есть лучший способ тестирования, который определяет поведение класса Stack. Идея заключается в том, что у вас есть взаимно-однозначное соответствие между классами поведения и методами тестирования. Итак, одно поведение заключается в том, что IsEmpty в пустом стеке возвращает true. Другой заключается в том, что нажатие одного элемента делает стек не пустым. Затем я написал бы тесты в формате Arrange / Act / Assert в соответствии с этими простыми английскими предложениями, определяющими эти поведения в формате:

MethodName_StateOfTheObject_ExpectedResult

Так что для поведения, упомянутого выше:

[TestMethod]
IsEmpty_OnEmptyStack_ReturnsTrue

[TestMethod]
Push_OnEmptyStack_MakesStackNotEmpty

Я бы посоветовал вам подумать о поведении, которое вы пытаетесь протестировать с помощью описанных выше методов, а затем сопоставить это поведение с тестами. Например:

[TestMethod]
ToList_OnEmptyString_ReturnsEmptyList

[TestMethod]
ToList_OnStringWithDelimiters_ReturnsListWithTokensSeparatedByDelemiter

[TestMethod]
ToList_OnStringWithoutDelimiters_ReturnsListWithOneString

Больше информации здесь

4 голосов
/ 14 апреля 2011

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

Так что нет:

  • TestFunctionWithListOfNumbers
  • и TestFunctionWithListOfStrings

но возможно:

  • TestFunctionWithStudentIDs
  • и TestFunctionWithStudentNames
2 голосов
/ 14 апреля 2011

Я склонен писать имена тестов более заданным образом, когда, тогда. Это делает название теста многословным, но говорит мне, что намеревалась сделать тестируемая функция. Так что в вашем случае у меня были бы тесты как

[TestMethod]
public void GivenSingleCharDelimeter_ToList_Returnsxxx()
[TestMethod]
public void GivenCharArrayDelimeter_ToList_Returnsxxx()
...