Czy moje testy jednostkowe są dobre?

Odpowiedz Nowy wątek
2019-07-09 09:52
0

Hej, wciąż się uczę pisania testów jednostkowych, dlatego będę wdzięczny za wszelkie uwagi i konstruktywną krytykę mojego kodu, zanim się zabiorę za testowanie kolejnych klas. Ciekaw jestem czy coś byście zrobili inaczej lub dołożyli. Wykorzystuję xUnit, Moq i Prism.Core.

Z racji objętości kodu zdecydowałem się jedynie umieścić link do GitHub moich testów.

A tutaj jest link do testowanej klasy modelu widoku.

Z góry dziękuję!

Pozostało 580 znaków

2019-07-09 10:40
1

Też ostatnio trochę piszę testów ale czy takie mają sens?

[Fact]
        public void CommandCompletedControlsSetup_Called_ResetsAllItsVisibiliProperties()
        {
            _viewModel.UpdateStatusBar = 1;
            _viewModel.VisibilityStatusBar = true;
            _viewModel.ProgressDisplay = "some txt";
            _viewModel.WorkStatus = "some txt";
            _viewModel.VisibilityCancellingMsg = false;
            _viewModel.VisibilityCancelTestingBtn = true;
            _viewModel.VisibilityTestingBtn = false;
            _viewModel.VisibilityCancelUpdatingBtn = true;
            _viewModel.VisibilityUpdatingBtn = false;

            _viewModel.CommandCompletedControlsSetup();

            _viewModel.UpdateStatusBar = 0;
            _viewModel.VisibilityStatusBar = false;
            _viewModel.ProgressDisplay = "";
            _viewModel.WorkStatus = "";
            _viewModel.VisibilityCancellingMsg = true;
            _viewModel.VisibilityCancelTestingBtn = false;
            _viewModel.VisibilityTestingBtn = true;
            _viewModel.VisibilityCancelUpdatingBtn = false;
            _viewModel.VisibilityUpdatingBtn = true;
        }

        [Fact]
        public void ResetControls_Called_ResetsAllItsVisibiliProperties()
        {
            _viewModel.AllControlsEnabled = false;
            _viewModel.VisibilityCancellingMsg = true;

            _viewModel.ResetControls();

            _viewModel.AllControlsEnabled = true;
            _viewModel.VisibilityCancellingMsg = false;
        }
edytowany 2x, ostatnio: szydlak, 2019-07-09 10:41
Zdecydowanie nie mają, miałem asertować, przynejmniej mam pewność, że ktoś do nich zajrzał ;p dzięki - bakunet 2019-07-09 16:52
Mam podobne nazewnictwo, ale zamiast CommandCompletedControlsSetup_Called_ResetsAllItsVisibiliProperties mój styl to CommandCompletedControlsSetup_WhenCalled_ShouldResetAllItsVisibiliProperties. I dodatkowo oprócz rozdzielania sekcji AAA nowymi liniami używam komentarzy //Arrange, //Act i //Assert. Twój styl trochę bardziej oszczędza miejsce. - Burmistrz 2019-07-11 06:17

Pozostało 580 znaków

2019-07-09 10:55
2

Tak na szybko to zwróciłbym uwagę na nazewnictwo testów:
PopulateLists_PopulatesLists - masło maślane :)
Tak aby nazwa testu wprost pokazywała twoje zamiary: w jakim stanie jest system -> co wykonujesz -> jaki rezultat oczekujesz.
Konwencji nazewniczych jest sporo. Wybierz odpowiednią dla siebie, teamu, projetu
https://dzone.com/articles/7-popular-unit-test-naming

Ciekawa uwaga, chętnie poczytam, bo każdy trochę inaczej rozpatruje kwestię nazewnictwa testów - bakunet 2019-07-09 16:56

Pozostało 580 znaków

2019-07-09 11:32
1

Ja chyba nie rozumiem takiego testu - ustawiasz pewne cechy ViewModelu, uruchamiasz na nim pewną metodę, ustawiasz cechy ponownie. A gdzie sprawdzenie czegokolwiek?

Haha, miałem asertować, mój błąd. - bakunet 2019-07-09 16:51

Pozostało 580 znaków

2019-07-10 06:10
0

Btw., testuję metody które mają resetować kilka własności i generalnie to test się sprowadza do wylistowania ich, odpalenia metody i asertowania tych własności, jak niżej:

public class ComputeServiceTests
    {
        private ComputeService _serviceClass;
        public ComputeServiceTests()
        {
            _serviceClass = new ComputeService();
        }

        [Fact]
        public void ResetComputeVariables_UpdatesProperties()
        {
            _serviceClass.DictValue = 10;
            _serviceClass.FinalResult = 10;
            _serviceClass.Result = 10;
            _serviceClass.SiblingIndex = 10;
            _serviceClass.Counter = 10;
            _serviceClass.ChildFromList = null;

            _serviceClass.ResetComputeVariables();

            Assert.Equal(1, _serviceClass.DictValue);
            Assert.Equal(0, _serviceClass.FinalResult);
            Assert.Equal(0, _serviceClass.Result);
            Assert.Equal(0, _serviceClass.SiblingIndex);
            Assert.Equal(0, _serviceClass.Counter);
            Assert.NotNull(_serviceClass.ChildFromList);
        }
    }

Czy da się to zrobić jakoś bardziej elegancko?

A poniżej SUT:

/// <summary>
        /// resets properties used in various methods
        /// </summary>
        public void ResetComputeVariables()
        {
            DictValue = 1;
            FinalResult = 0;
            Result = 0;
            SiblingIndex = 0;
            Counter = 0;
            ChildFromList = new LoadedHorse();
        }
edytowany 1x, ostatnio: bakunet, 2019-07-10 06:12

Pozostało 580 znaków

2019-07-11 02:20
1

Możesz użyć FluentAssertions i tam będziesz mógł to zrobić jedną linijką w stylu: _serviceClass.ShouldBeEquivalentTo(_expected).
Tak ogólnie, to nie jestem pewien, czy warto pisać takie testy do GUI.


"HUMAN BEINGS MAKE LIFE SO INTERESTING. DO YOU KNOW, THAT IN A UNIVERSE SO FULL OF WONDERS, THEY HAVE MANAGED TO INVENT BOREDOM."
Serio...? :D - Bączek 2019-07-11 02:49
@somekind: Tak ogólnie, to nie jestem pewien, czy warto pisać takie testy do GUI. nawet jeśli testuję własności do których kontrolki są bindowane? - bakunet 2019-07-11 13:14

Pozostało 580 znaków

2019-07-11 05:40
1

@bakunet:

Do testowania widoku służą testy akceptacyjne, a nie jednostkowe.

To, co powinieneś przetestować jednostkowo to wewnętrzne składniki (jednostki) domeny ewentualnie jakieś utilsy.

No ale u ciebie za bardzo się nie da skoro jedna funkcja ma grubo około 300 lini.

edytowany 1x, ostatnio: Bączek, 2019-07-11 05:41
Pokaż pozostałe 2 komentarze
Mowiąc widok mam na myśli UI. Testy akceptacyjne funkcyjne to raczej testy blackboxa. - Bączek 2019-07-11 13:59
Jak to co mam na myśli.? No po prostu jednostki domeny. - Bączek 2019-07-11 14:00
Spoko, będę miał na uwadze temat testów UI. Dzięki. A jak chodzi o jednostki domeny to jest dla mnie wciąż enigmatyczne określenie, niestety, ale to bierze się raczej z braku znajomości terminologii. - bakunet 2019-07-11 18:04
@Bączek: P.S. Sugerujesz, że powinienem porozbijać niektóre metody na drobniejsze dla ułatwienia testowania? - bakunet 2019-07-11 18:20
Oczywiście na las tych ifów pasował by jakiś kompozyt, pyłek, strategia czy nawt metoda szablonowa i tak dalej. - Bączek 2019-07-11 23:31

Pozostało 580 znaków

2019-07-12 02:09
0

Pomijając wzorce, nazewnictwo, to unit testy mają testować (nietrywialną) logikę aplikacyjną w najmniejszych sensownych jednostkach operacyjnych(stąd i nazwa).

Czyli nie są od testowania resetu kontrolek czy czyszczenia propertek, bo to jest raczej trywialne. No, chyba, że masz tam faktycznie logikę, która tym steruje(nie patrzyłem w kod, opieram się na wątku). Z tym, że wspomniany case też został wyjaśniony :)

Dlatego też nie da się jednostkowa przetestować metody, która wyciąga dane, mapuje, przerabia i woła trzydzieści innych metod - tych jednostek tam jest... No, dość dużo ;)

Dzięki za wyjaśnienie. Teraz żałuję że nie zabrałem się za aplikację TDD, metody pewnie by wyglądały zupełnie inaczej. - bakunet 2019-07-12 04:27
Człowiek się uczy na własnych doświadczeniach. Nie ma co żałować, trzeba wyciągnąć wnioski i lecieć dalej ;) - Klojtex 2019-07-12 12:54

Pozostało 580 znaków

2019-07-12 04:03
0

A co ta aplikacja w ogóle robi.? Próbowałem coś zrozumieć z TODO'sa, ale tam jakieś więzienne grypsy są:

jak przybral to zle czy kon zmienil ostatnio trenera - jak tak to dobrze, bedzie chcial sie wykazac jak klacz wystawiana vs ogierom, to pozytywnie nie da sie - shipping - czy kon przyjezdza?

Pokaż pozostałe 43 komentarze
Patrze na ten kod i sobie uwiadamiam jak programowania obiektowe jest nużące i rozwlekłe, przydałoby się więcej programowania funkcyjnego ;) Powodzenia 😊✊🏻✊🏻 - Visual Code 2019-07-13 12:36
@Visual Code: rozumiem, szpila wbita, ale co byś zmienił, co Ci się nie podoba w tym kodzie? Zbyt rozbudowane metody, architektura do bani, czy po prostu zajmujesz się na co dzień czymś innym i byś nigdy się programowanie obiektowe nie zabierał? - bakunet 2019-07-13 12:50
@Visual Code lol. Co ma do tego programowanie obiektowe? Po pierwsze język ma znaczenie - kod obiektowy w C# inaczej będzie wyglądał niż np. w Pythonie. Po drugie realizacja tego kodu (kod może być ładny, brzydki - to zależy od programisty). Co jeśli ci powiem, że często widuję kod funkcyjny, który wygląda jak koszmar? (większość projektów JavaScript korzystających z Reduxa). Czy to znaczy, że p. funkcyjne jest nużące i rozwlekłe? Czy mamy wywalić cały paradygmat tylko dlatego, że ludzie w nim nie umieją pisać albo że język nie jest przystosowany do danego języka? - LukeJL 2019-07-13 12:52
*język nie jest przystosowany do danego paradygmatu, miało być - LukeJL 2019-07-13 12:53
Wy po prostu piszecie w złych językach, ja piszę w Miranda to jest dopiero miód. A nie jakieś syfy typu C# czy Javascript. :D - Bączek 2019-07-13 12:59

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 0, botów: 1

Robot: CCBot