1 TEST WELL 2014 GRZEGORZ GAŁĘZOWSKI MOTOROLA SOLUTIONS 6 MAR 2014 1Title Page Option 3 Solid-colored Background Date/location information is Arial16pt. Headline copy is Arial Bold 54pt in all caps. Use Paragraph Line Spacing Multiple of 0.8 with 0pt spacing before and after. Presenter information is Arial Bold 18pt in all caps. The Paragraph Line Spacing is Exactly 0.9pt with 0pt spacing before and after. Background can be changed to any color is white. GRZEGORZ GAŁĘZOWSKI MOTOROLA SOLUTIONS 1
2 NIE ROZWIĄZUJ W TESTACH JEDNOSTKOWYCH PROBLEMÓW Z TESTOWANYM KODEMTitle Page Option 3 Solid-colored Background Date/location information is Arial16pt. Headline copy is Arial Bold 54pt in all caps. Use Paragraph Line Spacing Multiple of 0.8 with 0pt spacing before and after. Presenter information is Arial Bold 18pt in all caps. The Paragraph Line Spacing is Exactly 0.9pt with 0pt spacing before and after. Background can be changed to any color is white. GRZEGORZ GAŁĘZOWSKI MOTOROLA SOLUTIONS 2
3 BĘDZIE O... TESTACH JEDNOSTKOWYCH I PROJEKTOWANIU ORAZ ICH ZWIĄZKUNA 5 PRZYKŁADACH Agenda Slide Example Note: All slide titles in deck are 44pt BOLD ALL CAPS Arial, Subject Titles 24pt Bold ALL CAPS, Arial. Title color should be consistent with color in presentation. To change title colors you will need to do so in Slide Master view. Images can be swapped out using any of the new brand imagery at go to page 21 for instructions on sizing/modifying. Image for agenda can have three sided bleed.
4
5 TESTY W MOIM ŚWIECIE... Section Slide Example – No Image, Solid Color TITLE ALL CAPS ARIAL 44 PT BOLD, line spacing .8 lines. A divider slide can use a color block on half the page, color consistent with color choice used in presentation. 5
6 Lista TODO Czy zaimplementowałem wszystko?
7 Analiza Czy wiem, co buduję?
8 Wykonywalna dokumentacjaCzego "klient" może od kodu oczekiwać?
9 Projektowanie Jak rozbić problem?
10 TESTY JEDNOSTKOWE DAWNIEJ I DZIŚSection Slide Example – No Image, Solid Color TITLE ALL CAPS ARIAL 44 PT BOLD, line spacing .8 lines. A divider slide can use a color block on half the page, color consistent with color choice used in presentation. 10
11 "the tests must be kept to the same level of high quality as the production code. (...) Duplication must be eliminated from them." Robert C. Martin
12 ROZWIĄZANIA NA POZIOMIE AUTOMATYZACJISection Slide Example – No Image, Solid Color TITLE ALL CAPS ARIAL 44 PT BOLD, line spacing .8 lines. A divider slide can use a color block on half the page, color consistent with color choice used in presentation. 12
13 Metody SetUp [SetUp] public void SetTheStage() { this.valueUsedEverywhere = 12; }
14 Dziedziczenie Klas [TestFixture] public class AuthorizationBehaviors : TestBase
15 Metody pomocnicze message = createMessageFor("Ala");
16
17 JAKOŚĆ JEDNOSTKI: SPÓJNOŚĆ I POWIĄZANIASection Slide Example – No Image, Solid Color TITLE ALL CAPS ARIAL 44 PT BOLD, line spacing .8 lines. A divider slide can use a color block on half the page, color consistent with color choice used in presentation. 17
18 Spójność ~ jednA rzecz A B C D
19 Spójność ~ jedna rzecz B A C D
20 Spójność ~ jedna rzecz B A C D
21 Powiązania – kogo klasa zna?B C D
22 Mocki – "symulatory" obiektówTEST
23 SPÓJNOŚĆ I POWIĄZANIA a testySection Slide Example – No Image, Solid Color TITLE ALL CAPS ARIAL 44 PT BOLD, line spacing .8 lines. A divider slide can use a color block on half the page, color consistent with color choice used in presentation. 23
24 Test jednostkowy to klient koduJednostka Test Test Test Test
25 Źle zaprojektowana jednostka...Test Klient Test Test Jednostka Test Test Test Test
26 ...jest trudno testowalnaKlient Test Test Jednostka Test Test Test Test
27 SŁUCHAJ ŚLEPO SWOICH TESTÓWSection Slide Example – No Image, Solid Color TITLE ALL CAPS ARIAL 44 PT BOLD, line spacing .8 lines. A divider slide can use a color block on half the page, color consistent with color choice used in presentation. 27
28 Korzyści z ˶słuchania testów˝Lepszy design produktu większa spójność mniej powiązań Lepsza utrzymywalność testów
29 PIĘĆ PRZYKŁADÓW 29 Section Slide Example – No Image, Solid ColorTITLE ALL CAPS ARIAL 44 PT BOLD, line spacing .8 lines. A divider slide can use a color block on half the page, color consistent with color choice used in presentation. 29
30 UWAGA! ZŁY KOD!
31 Przykład 1: nachodzenie zakresu testówSection Slide Example – No Image, Solid Color TITLE ALL CAPS ARIAL 44 PT BOLD, line spacing .8 lines. A divider slide can use a color block on half the page, color consistent with color choice used in presentation. 31
32 validation = new SanityValidation(); info = new PersonInfo(); infovalidation = new SanityValidation(); info = new PersonInfo(); info.Name = "Zenek"; info.Surname = "Kowalski"; info.Age = VALID_AGE; Assert.DoesNotThrow( () => validation.Of(info) );
33 validation = new SanityValidation(); info = new PersonInfo(); infovalidation = new SanityValidation(); info = new PersonInfo(); info.Name = "$"; info.Surname = "Kowalski"; info.Age = VALID_AGE; Assert.Throws
34 validation = new SanityValidation(); info = new PersonInfo(); infovalidation = new SanityValidation(); info = new PersonInfo(); info.Name = "Zenek"; info.Surname = "$"; info.Age = VALID_AGE; Assert.Throws
35 validation = new SanityValidation(); info = new PersonInfo(); infovalidation = new SanityValidation(); info = new PersonInfo(); info.Name = "Zenek"; info.Surname = "Kowalski"; info.Age = VALID_AGE – 1; Assert.Throws
36 Póki co... Name Surname Age
37 Utrzymywalność Name Surname Age Country
38 Nachodzenie na siebie zakresów testów.Utrzymywalność Name Surname Age Country Wskazówka: Nachodzenie na siebie zakresów testów.
39 ˶Nadpisz jedno pole˝ - OK, ale...validation = new SanityValidation(); info = CreateValidPersonInfo(); info.Name = CreateInvalidName(); Assert.Throws
40 ˶Nadpisz jedno pole˝ - OK, ale...validation = new SanityValidation(); info = CreateValidPersonInfo(); info.Name = CreateInvalidName(); Assert.Throws
41 SanityValidation mała spójność Testy Name Of(x) Walidacja NameTesty Surname Walidacja Surname Walidacja Surname Testy Age Walidacja Age Walidacja Age
42 zachowania sobie przeszkadzająSanityValidation Testy Name Of(x) Walidacja Name Testy Surname Walidacja Surname Testy Age Walidacja Age
43 zachowania sobie przeszkadzająSanityValidation Testy Name Of() Walidacja Name Testy Surname Walidacja Surname Walidacja Surname Testy Age Walidacja Age Walidacja Age
44 zachowania sobie przeszkadzająSanityValidation Testy Name Of(x) Walidacja Name Testy Surname Walidacja Surname Walidacja Surname Testy Age Walidacja Age Walidacja Age
45 Podział lepsza spojnosćSanityValidation PartialValidations Of(x) Walidacja Name Walidacja Surname PersonInfo Walidacja Age
46 Uwspólnienie SanityValidation PartialValidations Of(x)Walidacja Napisu PersonInfo Walidacja Minimum
47 Mamy dane i funkcję SanityValidation PartialValidations Of(x)Walidacja Napisu PersonInfo Walidacja Minimum
48 lepsza abstrakcja Person PartialValidations Validate()Walidacja Napisu PersonInfo Walidacja Minimum
49 Test Person: używa walidacji?Test Validate() Validate() PersonInfo Partial Validations Mock
50 Testy walidacji napisuPartialValidations Testy Napisu Walidacja Napisu Testy Minimum Walidacja Minimum
51 Test walidacji minimumValidations Testy Napisu Walidacja Napisu Testy Minimum Walidacja Minimum
52 Przykład 2: kombinacje funkcjonalnościSection Slide Example – No Image, Solid Color TITLE ALL CAPS ARIAL 44 PT BOLD, line spacing .8 lines. A divider slide can use a color block on half the page, color consistent with color choice used in presentation. 52
53 var processing = new MessageProcessing(); messageProcessingvar processing = new MessageProcessing(); messageProcessing.Encryption = true; messageProcessing.Translation = true; messageProcessing.Compression = true; processing.For(message); ...
54 Wskazówka: Eksplozja Kombinacjivar processing = new MessageProcessing(); messageProcessing.Encryption = true; messageProcessing.Translation = true; messageProcessing.Compression = true; processing.For(message); ... Wskazówka: Eksplozja Kombinacji
55 [TestCase(true, true, true)] public void ShouldProcessMessage( bool encrypt, bool translate, bool compress) { processing = new MessageProcessing(); processing.Encryption = encrypt; processing.Translation = translate; processing.Compression = compress; //...
56 [TestCase(true , true , true )] [TestCase(false, true , true )] [TestCase(true , false, true )] [TestCase(true , true , false)] [TestCase(false, false, true )] [TestCase(true , false, false)] [TestCase(false, true , false)] [TestCase(false, false, false)] public void ShouldProcessMessage( bool encrypt, bool translate, bool compress)
57 Zbyt wiele odpowiedzialnościMessageProcessing For(msg) Encryption Translation Walidacja Surname Compression Walidacja Age
58 Podział obiektów Encryption For(msg) Translation CompressionMessageProcessing For(msg) Encryption Translation Compression
59 Wyłączanie transformacjiMessageProcessing For(msg) NullEncryption Translation Compression
60 Test przetwarzania - lepiej, ale...MessageProcessing (1) For(msg) (2) (3)
61 Test przetwarzania - lepiej, ale...MessageProcessing For(msg) Wskazówka: Dużo różnych mocków na test
62 Wspólny mianownik... Encryption For(msg) Translation CompressionMessageProcessing For(msg) Encryption Translation Compression
63 Podział obiektów Transformation Transformation For(m) TransformationMessageProcessing Transformation Transformation For(m) Transformation Translation Encryption Compression
64 Test Przetwarzania – jeszcze razMessageProcessing For(m)
65 Przykład 3: łańcuchy zależnościSection Slide Example – No Image, Solid Color TITLE ALL CAPS ARIAL 44 PT BOLD, line spacing .8 lines. A divider slide can use a color block on half the page, color consistent with color choice used in presentation. 65
66 Mocki - legenda Utworzenie: mock = Substitute.For
67 system = Substitute. For
68 Zestawianie łańcucha mockówTest Name
69 Wszystko widoczne publicznieKlient System Radio Owner Name
70 Problem z zależnościamiKlient System Radio Owner Name
71 Problem z zależnościamiKlient System Radio Wskazówka: mocki zwracające mocki Owner Name
72 najprostsze RozwiązanieKlient System Radio Owner RadioOwnerName
73 Łatwiejsze testy Klient RadioOwnerName
74 Przykład 4: muszę testować prywatne metodySection Slide Example – No Image, Solid Color TITLE ALL CAPS ARIAL 44 PT BOLD, line spacing .8 lines. A divider slide can use a color block on half the page, color consistent with color choice used in presentation. 74
75 - Chcę testować prywatną metodęObiekt A() B() D() C()
76 - Zrób to przez publiczne APITest Obiekt A() B() D() C()
77 - Ale ona jest na tyle odrębna...Test 2 Obiekt A() B() D() C()
78 ... że chcę ją testować osobno.Obiekt A() Wskazówka: Chęć testowania prywatnych metod B() D() C()
79 - To ją wydziel! Test 2 Obiekt Inny Obiekt A() B() D() C()
80 Przykład 5: ciężki kontekstSection Slide Example – No Image, Solid Color TITLE ALL CAPS ARIAL 44 PT BOLD, line spacing .8 lines. A divider slide can use a color block on half the page, color consistent with color choice used in presentation. 80
81 configData = new ConfigData(); configData. GetHeader()configData = new ConfigData(); configData.GetHeader().SetStdState(StdState.SUBMITTED); configData.GetHeader().SetType(FileType.NECB); ge1 = CreateGroupEntry(1, TALKGROUP, null, configData.Id); ge2 = CreateGroupEntry(2, TALKGROUP, null, configData.Id); ge3 = CreateGroupEntry(3, MULTIGROUP, null, configData.Id); ge4 = CreateGroupEntry(4, MULTIGROUP, null, configData.Id); ge5 = CreateGroupEntry(5, MULTIGROUP, null, configData.Id); talkgroup1 = CreateTalkgroup(1, 1, null, configData.Id); talkgroup2 = CreateTalkgroup(1, 3, null, configData.Id); talkgroup3 = CreateTalkgroup(2, 0, null, configData.Id); talkgroup4 = CreateTalkgroup(3, 5, null, configData.Id); context = new ValidationObjectContext(configData);
82 pracochłonne ustawianie kontekstuconfigData = new ConfigData(); configData.GetHeader().SetStdState(StdState.SUBMITTED); configData.GetHeader().SetType(FileType.NECB); ge1 = CreateGroupEntry(1, TALKGROUP, null, configData.Id); ge2 = CreateGroupEntry(2, TALKGROUP, null, configData.Id); ge3 = CreateGroupEntry(3, MULTIGROUP, null, configData.Id); ge4 = CreateGroupEntry(4, MULTIGROUP, null, configData.Id); ge5 = CreateGroupEntry(5, MULTIGROUP, null, configData.Id); talkgroup1 = CreateTalkgroup(1, 1, null, configData.Id); talkgroup2 = CreateTalkgroup(1, 3, null, configData.Id); talkgroup3 = CreateTalkgroup(2, 0, null, configData.Id); talkgroup4 = CreateTalkgroup(3, 5, null, configData.Id); context = new ValidationObjectContext(configData); Wskazówka: pracochłonne ustawianie kontekstu
83 wnioski Słuchaj ślepo swoich testów Uważaj na:eksplozje kombinacji długie testy testowanie prywatnych metod mocki zwracające mocki ciężki kontekst Szukaj najpierw źródła problemu w designie
84 pytania? Słuchaj ślepo swoich testów Uważaj na:eksplozje kombinacji długie testy testowanie prywatnych metod mocki zwracające mocki ciężki kontekst Szukaj najpierw źródła problemu w designie
85 85 Thank you or Q&A wrap up slide example. Font arial 80pt.Legal disclaimer bottom of page arial 8pt font with I Protect iProtect Classification: Public MOTOROLA, MOTO, MOTOROLA SOLUTIONS and the Stylized M Logo are trademarks or registered trademarks of Motorola Trademark Holdings, LLC and are used under license. All other trademarks are the property of their respective owners. © 2010 Motorola, Inc. All rights reserved. 85
86 Tests As Design Rot RadarSynaesthesia S. Freeman, N. Pryce Test Reflexology A. Kolsky, S. Bain Tests As Design Rot Radar J. Grenning
87 Lepiej, ale... var encryption = Substitute.For
88 Dużo różnych mocków na testLepiej, ale... var encryption = Substitute.For
89 var transformations = new[] { Substitutevar transformations = new[] { Substitute.For
90 Co testy próbują powiedzieć?public bool Of(PersonInfo info) { if(info.Name == null) throw new InvalidValueException(); if(info.Surname == null) if(info.Age < VALID_AGE) }
91 var v = Substitute. For
92 var inbound = new InboundMessaging(var inbound = new InboundMessaging(...); var privateObject = new PrivateObject(inbound); var frame = (Frame)privateObject .Invoke("ParseInput", bytes); Assert.AreEqual(12, frame.Field1); Rozwiązanie 1: testuj przez publiczne API.
93 testowanie prywatnych metodvar inbound = new InboundMessaging(...); var privateObject = new PrivateObject(inbound); var frame = (Frame)privateObject .Invoke("ParseInput", bytes); Assert.AreEqual(12, frame.Field1); Wskazówka: testowanie prywatnych metod
94 var parsing = new InboundParsing(. ); var frame = parsingvar parsing = new InboundParsing(...); var frame = parsing.Of(bytes); Assert.AreEqual(12, frame.Field1);
95 Przykład: Inteligentne Mocki
96 mock. When(m => m. Process(WithAnyMessage()) )mock.When(m => m.Process(WithAnyMessage()) ).Do(() => { messageCount++; if(messageCount > 100) throw new CountExceededException(); Thread.Sleep(1000); }); TODO zastąpić pseudokodem
97 Wskazówka: "inteligentne" mockimock.When(m => m.Process(WithAnyMessage()) ).Do(() => { messageCount++; if(messageCount > 100) throw new CountExceededException(); Thread.Sleep(1000); }); Wskazówka: "inteligentne" mocki