c# unit test - соглашение об именах для перегруженных тестов методов

у меня есть несколько простых методов расширения в 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 ответов


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

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. Другое заключается в том, что нажатие одного элемента делает стек не пустым. Затем я бы написал тесты в Организовать / Действовать / Утверждать формат в соответствии с этими простыми английскими предложениями, определяющими эти поведения в формате:

MethodName_StateOfTheObject_ExpectedResult

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

[TestMethod]
IsEmpty_OnEmptyStack_ReturnsTrue

[TestMethod]
Push_OnEmptyStack_MakesStackNotEmpty

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

[TestMethod]
ToList_OnEmptyString_ReturnsEmptyList

[TestMethod]
ToList_OnStringWithDelimiters_ReturnsListWithTokensSeparatedByDelemiter

[TestMethod]
ToList_OnStringWithoutDelimiters_ReturnsListWithOneString

дополнительная информация здесь


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

не так:

  • TestFunctionWithListOfNumbers
  • и TestFunctionWithListOfStrings

но возможно:

  • TestFunctionWithStudentIDs
  • и TestFunctionWithStudentNames

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

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