Często zdarza się, że musimy napisać kilka testów dla wybranej metody podając za każdym razem inne dane wejściowe. U mnie z reguły kończyło się to pisaniem kilku identycznych metod testowych, które różniły się od siebie jedynie wartościami argumentów podawanych do testowanego kodu. Przykład poniżej.
Przykłady w F#, ale myślę, że każdy programista C# je zrozumie. Ten post jest kontynuacją wpisu o testach jednostkowych w F#. Pokazany niżej przykład jest znajduje się na GitHubie.
[<Test>] let ``is time 23:59:59 properly parsed``() = //arrange let time = "23:59:59" //act let parsedTime = Time.Parse(time) //assert Assert.That(parsedTime.Hour, Is.EqualTo(23)) Assert.That(parsedTime.Minute, Is.EqualTo(59)) Assert.That(parsedTime.Second, Is.EqualTo(59)) [<Test>] let ``is time 0:0:0 properly parsed``() = //arrange let time = "0:0:0" //act let parsedTime = Time.Parse(time) //assert Assert.That(parsedTime.Hour, Is.EqualTo(0)) Assert.That(parsedTime.Minute, Is.EqualTo(0)) Assert.That(parsedTime.Second, Is.EqualTo(0)) [<Test>] let ``is time 0:01:0 properly parsed``() = //arrange let time = "0:01:0" //act let parsedTime = Time.Parse(time) //assert Assert.That(parsedTime.Hour, Is.EqualTo(0)) Assert.That(parsedTime.Minute, Is.EqualTo(1)) Assert.That(parsedTime.Second, Is.EqualTo(0))
To nic innego jak powielanie tego samego kodu. Czegoś takiego chcemy uniknąć i z pomocą przychodzi nam atrybut TestCase dostępny w bibliotece nUnit. Najpierw kod po zmianach (GitHub):
[<TestCase("0:01:0", 0, 1, 0)>] [<TestCase("0:0:0", 0, 0, 0)>] [<TestCase("23:59:59", 23, 59, 59)>] let ``is time properly parsed``(time, parsedHour, parsedMinute, parsedSecond) = //act let parsedTime = Time.Parse(time) //assert Assert.That(parsedTime.Hour, Is.EqualTo(parsedHour)) Assert.That(parsedTime.Minute, Is.EqualTo(parsedMinute)) Assert.That(parsedTime.Second, Is.EqualTo(parsedSecond))
Prawda, że lepiej? Usuwamy powielony kod i zostawiamy tylko jedną metodę. Musimy pozwolić metodzie pobierać dane przez parametry. W pokazanym przykładzie pierwszym argumentem jest spodziewany wynik testu a w dalszej kolejności znajdują się parametry wejściowe. Nad metodą wstawiamy atrybut TestCase, którego argumenty odpowiadają argumentom metody testowej. Atrybut TestCase dodajemy tyle razy ile przypadków chcemy przetestować.
Po zmianach okienko TestExplorer w VisualStudio nadal pokaże nam trzy testy zamiast jednego i dodatkowo informuje jakie parametry wejściowe podajemy. Nie musimy się więc silić z umieszczaniem wartości parametrów w nazwie metody bo nazwy testów będą już je zawierać i nasze testy będą czytelne.
Dla ciekawskich dokumentacja nUnit na temat TestCase (pokazuje np. jak zmienić nazwę testu, jeśli typy argumentów wydają nam się zbędne).