• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Hack@macs 2014 test driven development & pair programing
 

Hack@macs 2014 test driven development & pair programing

on

  • 151 views

გიორგი მამალაძე - Test Driven Development & Pair Programming

გიორგი მამალაძე - Test Driven Development & Pair Programming

video: https://www.youtube.com/watch?v=yGg97JeyxWE

Statistics

Views

Total Views
151
Views on SlideShare
151
Embed Views
0

Actions

Likes
0
Downloads
0
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Hack@macs 2014 test driven development & pair programing Hack@macs 2014 test driven development & pair programing Presentation Transcript

    • Test Driven Development & Pair Programing გიორგი მამალაძე
    • George Mamaladze Software Architect Siemens I IA AS CTO @gmamaladze
    • დამიწერია და გამიშვია ავტომატიზირებული ტესტები.
    • ჩემს მიერ დაწერილი კოდის უმეტესობა დაფარულია ავტომატიზირებული ტესტებით.
    • ტესეტების წერაზე დროს არ ვხარჯავ. მირჩევნია კოდის წერა.
    • The Five Orders of Ignorance არცოდნის 5 ხარისხი 0th Order Ignorance რაიმეს ობიექტურად და დანამდვილებით ცოდნა
    • The Five Orders of Ignorance არცოდნის 5 ხარისხი 0th Order Ignorance რაიმეს ობიექტურად და დანამდვილებით ცოდნა 1st Order Ignorance როდესაც იცი რომ არ იცი
    • The Five Orders of Ignorance არცოდნის 5 ხარისხი 0th Order Ignorance რაიმეს ობიექტურად და დანამდვილებით ცოდნა 1st Order Ignorance როდესაც იცი რომ არ იცი 2nd Order Ignorance როდესაც არ იცი რომ არ იცი
    • The Five Orders of Ignorance არცოდნის 5 ხარისხი 0th Order Ignorance რაიმეს ობიექტურად და დანამდვილებით ცოდნა 1st Order Ignorance როდესაც იცი რომ არ იცი 2nd Order Ignorance როდესაც არ იცი რომ არ იცი 3rd Order Ignorance როდესაც ისიც კი არ იცი როგორ დაადგინო რომ არ იცი
    • The Five Orders of Ignorance არცოდნის 5 ხარისხი 4th Order Ignorance მაშინ როდესაც სარეთოდ წარმოდგენა არ გაქვს Five Orders of Ignorance-ის არცოდნის 5 ხარისხის არსებობის შესახებაც კი.
    • • ტესტირების ევოლუცია • ნამდვილი Unit ტესტი • TDD & PP • ტესტის აგებულება და ენა საკითხები
    • Q: რა ფუნქცია აქვთ ტესტებს? A: შეცდომების (Bug-ების) პოვნა.
    • ტესტი დებაგერის სანაცვლოდ
    • ტესტირების ევოლუცია
    • ტესტირების გამოყოფა მენეჯერი პროგრამისტები Coding Testing ტესტერები
    • ტესტირების ევოლუცია 1. Automate framework pretends to be a user
    • Scenario Tests Test Driver Application Action Reaction
    • Scenario Tests Test Driver Application SUT Stimulus Asserts • Expectation 1 R • Expectation 2 R • Expectation 3 S Test Result
    • ტესტირების ევოლუცია 1. Automate framework pretends to be a user slow / flaky / corner cases not tested
    • Code Path Coverage public void DoSomething() { readInput(); processData(); if (!isDiskFull()) { writeOutput(); } else { showError(); }; }
    • public void DoSomething() { readInput(); processData(); if (!isDiskFull()) { writeOutput(); } else { showError(); }; } Happy Path Corner Case Code Path Coverage
    • ტესტირების ევოლუცია 1. Automate framework pretends to be a user slow / flaky / corner cases not tested 2. Break down simulate dependencies
    • Test Driver Break Down Application Step 1 Replace user with robot
    • Application Data Simulator Test Driver Functional Tests Step 1 Replace user with robot Step 2 Break down and simulate Presentation Business Logic Data Layer
    • ტესტირების ევოლუცია 1. Automate framework pretends to be a user slow / flaky / corner cases not tested 2. Break down simulate dependencies much faster / can simulate
    • ტესტირების ევოლუცია 1. Automate framework pretends to be a user slow / flaky / corner cases not tested 2. Break down simulate dependencies much faster / can simulate still need debugging
    • ტესტირების ევოლუცია 1. Automate framework pretends to be a user slow / flaky / corner cases not tested 2. Break down simulate dependencies much faster / can simulate still need debugging 3. Break down even more
    • ტესტირების ევოლუცია 1. Automate framework pretends to be a user slow / flaky / corner cases not tested 2. Break down simulate dependencies much faster / can simulate still need debugging 3. Break down even more
    • ტესტირების ევოლუცია Scenario Tests Functional Tests Unit Tests
    • Scenario Tests Unit Tests Functional Tests # of Tests Execution Time Test individual classes / methods in isolation Test collections of classes as subsystems Tests the whole system pretending to be a user More: TestPyramid ტესტირების ევოლუცია
    • ნუთუ არასაკმარისია მხოლოდ ერთი სახის ტესტი?
    • Why should I write a unit test if we still need to have the functional one? Test Probability of deffect Cost To Run Action At Fault Flashlight 50 ??? Light Bulb 1 from 5 1 Replace Battery 1 from7 1 Replace Switch 1 from11 1 Replace Wiring 1 from 13 2 Replace ?????
    • 1/71/5 1/11 1/13 0,140,20 0,09 0,07 ≈ 0,51 1/2
    • ნამდვილი Unit test-ი
    • JUnit / NUnit ! = unit test The „real“ Unit Tests Tests that do these things aren't bad. Often they are worth writing, and they can be written in a unit test harness. However, it is important to be able to separate them from true unit tests so that we can keep a set of tests that we can run fast whenever we make our changes. Michael Feathers, "A Set of Unit Testing Rules" •It talks to the database •It communicates across the network •It touches the file system •You have to do special things to your environment (such as editing config files) to run it. •It runs longer than 0.1 second •It can't run at the same time as any of your other unit tests A test is not a unit test if:
    • რა პრობლემებთანაა დაკავშირებული Unit- Test-ების შექმნა?
    • Test Driver Class Under Test Stimulus Asserts
    • Test Driver Class Under Test Stimulus Asserts At the beginning you will realize real unit testing is hard! Your classes must be designed to be testable.
    • Test Driver Class Under Test Other Class Other Class Other Class Object Instantiated Object Passed In Global Object
    • Test Driver Class Under Test Other Class Other Class Other Class CPU Intensive Other Class Other Class Destructive operation Other Servers File System Other Class Object Instantiated Object Passed In Global Object Seam
    • Test Driver Class Under Test Other Class Other Class Other Class Friendly Friendly Friendly Seam Object Instantiated Object Passed In Global Object
    • Test Driver Class Under Test Object Instantiated Object Passed In Global Object Friendly Friendly Friendly Seam
    • Business Logic Object Graph Construction & Lookup
    • Test Driver Class Under Test Object Instantiated Object Passed In Global Object Friendly Friendly Friendly Seam
    • Test Driver Class Under Test Mock Stub Fake http://www.martinfowler.com/bliki/TestDouble.html Test Doubles JUnit Code
    • Test Doubles •Dummy objects are passed around but never actually used. •Fake objects actually have working implementations, but usually take some shortcut. •Stubs provide canned answers to calls made during the test. •Spies are stubs that also record some information based on how they were called. •Mocks are pre-programmed with expectations which form a specification of the calls they are expected to receive. http://www.martinfowler.com/bliki/TestDouble.html
    • TDD & PP
    • What is TDD?
    • TDD Katas
    • 1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, Fizz Buzz, 16, 17, Fizz, 19, Buzz, Fizz, 53 5 3 Fizz Buzz
    • using NUnit.Framework; [TestFixture] public class FizzBuzzTests { }
    • [Test] public void TranslateOne() { string result = Translator.Translate(1); Assert.That(result, Is.EqualTo("1")); } public class Translator { public static string Translate(int i) { throw new NotImplementedException(); } }
    • [Test] public void TranslateOne() { string result = Translator.Translate(1); Assert.That(result, Is.EqualTo("1")); } public static string Translate(int i) { return "1"; }
    • [Test] public void TranslateTwo() { string result = Translator.Translate(2); Assert.That(result, Is.EqualTo("2")); } public static string Translate(int i) { return i.ToString(); }
    • [TestCase(1, "1")] public void Translate(int input, string expected) { string result = Translator.Translate(input); Assert.That(result, Is.EqualTo(expected)); } public static string Translate(int i) { return i.ToString(); }
    • [TestCase(1, "1")] [TestCase(2, "2")] public void Translate(int input, string expected) { string result = Translator.Translate(input); Assert.That(result, Is.EqualTo(expected)); } public static string Translate(int i) { return i.ToString(); }
    • [TestCase(1, "1")] [TestCase(2, "2")] [TestCase(3, "Fizz")] public void Translate(int input, string expected) { string result = Translator.Translate(input); Assert.That(result, Is.EqualTo(expected)); } public static string Translate(int i) { return i.ToString(); }
    • [TestCase(1, "1")] [TestCase(2, "2")] [TestCase(3, "Fizz")] public void Translate(int input, string expected) { string result = Translator.Translate(input); Assert.That(result, Is.EqualTo(expected)); } public static string Translate(int i) { if (i == 3) return "Fizz"; return i.ToString(); }
    • [TestCase(1, "1")] [TestCase(2, "2")] [TestCase(3, "Fizz")] [TestCase(6, "Fizz")] public void Translate(int input, string expected) { string result = Translator.Translate(input); Assert.That(result, Is.EqualTo(expected)); } public static string Translate(int i) { if (i == 3) return "Fizz"; return i.ToString(); }
    • [TestCase(1, "1")] [TestCase(2, "2")] [TestCase(3, "Fizz")] [TestCase(6, "Fizz")] public void Translate(int input, string expected) { string result = Translator.Translate(input); Assert.That(result, Is.EqualTo(expected)); } public static string Translate(int i) { if (i % 3 == 0) return "Fizz"; return i.ToString(); }
    • [TestCase(1, "1")] [TestCase(2, "2")] [TestCase(3, "Fizz")] [TestCase(5, "Buzz")] [TestCase(6, "Fizz")] public void Translate(int input, string expected) { string result = Translator.Translate(input); Assert.That(result, Is.EqualTo(expected)); } public static string Translate(int i) { if (i % 3 == 0) return "Fizz"; return i.ToString(); }
    • [TestCase(1, "1")] [TestCase(2, "2")] [TestCase(3, "Fizz")] [TestCase(5, "Buzz")] [TestCase(6, "Fizz")] public void Translate(int input, string expected) { string result = Translator.Translate(input); Assert.That(result, Is.EqualTo(expected)); } public static string Translate(int i) { if (i % 3 == 0) return "Fizz"; if (i == 5) return "Buzz"; return i.ToString(); }
    • [TestCase(1, "1")] [TestCase(2, "2")] [TestCase(3, "Fizz")] [TestCase(5, "Buzz")] [TestCase(6, "Fizz")] [TestCase(10, "Buzz")] public void Translate(int input, string expected) { string result = Translator.Translate(input); Assert.That(result, Is.EqualTo(expected)); } public static string Translate(int i) { if (i % 3 == 0) return "Fizz"; if (i == 5) return "Buzz"; return i.ToString(); }
    • [TestCase(1, "1")] [TestCase(2, "2")] [TestCase(3, "Fizz")] [TestCase(5, "Buzz")] [TestCase(6, "Fizz")] [TestCase(10, "Buzz")] public void Translate(int input, string expected) { string result = Translator.Translate(input); Assert.That(result, Is.EqualTo(expected)); } public static string Translate(int i) { if (i % 3 == 0) return "Fizz"; if (i % 5 == 0) return "Buzz"; return i.ToString(); }
    • [TestCase(1, "1")] [TestCase(2, "2")] [TestCase(3, "Fizz")] [TestCase(5, "Buzz")] [TestCase(6, "Fizz")] [TestCase(10, "Buzz")] public static string Translate(int i) { if (ShouldFizz(i)) return "Fizz"; if (ShouldBuzz(i)) return "Buzz"; return i.ToString(); } private static bool ShouldBuzz(int i) { return i % 5 == 0; } private static bool ShouldFizz(int i) { return i % 3 == 0; }
    • [TestCase(1, "1")] [TestCase(2, "2")] [TestCase(3, "Fizz")] [TestCase(5, "Buzz")] [TestCase(6, "Fizz")] [TestCase(10, "Buzz")] [TestCase(15, "FizzBuzz")] public static string Translate(int i) { if (ShouldFizz(i)) return "Fizz"; if (ShouldBuzz(i)) return "Buzz"; return i.ToString(); } private static bool ShouldBuzz(int i) { return i % 5 == 0; } private static bool ShouldFizz(int i) { return i % 3 == 0; }
    • [TestCase(1, "1")] [TestCase(2, "2")] [TestCase(3, "Fizz")] [TestCase(5, "Buzz")] [TestCase(6, "Fizz")] [TestCase(10, "Buzz")] [TestCase(15, "FizzBuzz")] public static string Translate(int i) { string returnString = string.Empty; if (ShouldFizz(i)) returnString += "Fizz"; if (ShouldBuzz(i)) returnString += "Buzz"; if (string.IsNullOrEmpty(returnString)) { returnString = i.ToString(); } return returnString; }
    • [TestCase(1, "1")] [TestCase(2, "2")] [TestCase(3, "Fizz")] [TestCase(5, "Buzz")] [TestCase(6, "Fizz")] [TestCase(10, "Buzz")] [TestCase(15, "FizzBuzz")] public static string Translate(int i) { string returnString = string.Empty; returnString = Fizzy(i, returnString); if (ShouldBuzz(i)) returnString += "Buzz"; if (string.IsNullOrEmpty(returnString)) { returnString = i.ToString(); } return returnString; } private static string Fizzy(int i, string returnString) { return returnString + (ShouldFizz(i) ? "Fizz" : string.Empty); }
    • public static string Translate(int i) { string returnString = string.Empty; returnString = Fizzy(i, returnString); returnString = Buzzy(i, returnString); if (string.IsNullOrEmpty(returnString)) { returnString = i.ToString(); } return returnString; } private static string Buzzy(int i, string returnString) { return returnString + (ShouldBuzz(i) ? "Buzz" : string.Empty); } [TestCase(1, "1")] [TestCase(2, "2")] [TestCase(3, "Fizz")] [TestCase(5, "Buzz")] [TestCase(6, "Fizz")] [TestCase(10, "Buzz")] [TestCase(15, "FizzBuzz")]
    • [TestCase(1, "1")] [TestCase(2, "2")] [TestCase(3, "Fizz")] [TestCase(5, "Buzz")] [TestCase(6, "Fizz")] [TestCase(10, "Buzz")] [TestCase(15, "FizzBuzz")] public static string Translate(int i) { string returnString = string.Empty; returnString = Fizzy(i, returnString); returnString = Buzzy(i, returnString); returnString = Other(i, returnString); return returnString; } private static string Other(int i, string returnString) { return string.IsNullOrEmpty(returnString) ? i.ToString() : returnString; }
    • [TestCase(1, "1")] [TestCase(2, "2")] [TestCase(3, "Fizz")] [TestCase(5, "Buzz")] [TestCase(6, "Fizz")] [TestCase(10, "Buzz")] [TestCase(15, "FizzBuzz")] public static IList<Func<int, string, string>> Rules = new List<Func<int, string, string>> { Fizzy, Buzzy, Other }; public static string Translate(int i) { string returnString = string.Empty; foreach (var rule in Rules) { returnString = rule(i, returnString); } return returnString; }
    • TDD & PP write failing test write code to passconsolidate
    • TDD & PP write failing test write code to passconsolidate
    • TDD & PP write failing test write code to passconsolidate
    • TDD & PP write failing test write code to passconsolidate
    • TDD & PP write failing test write code to passconsolidate
    • ტესტის აგებულება და ენა
    • Cyclomatic complexity of 1 (no conditionals) Containing three sections Prepare: Declaration and initialization Do: Do actual work – invoke the member under test. Assert: Assert execution results. The Structure of a Unit Test
    • In ideal case every test contains exactly tree lines: The Structure of a Unit Test Terminology: •Target (target) •Source data •Expectation (expected) •Actual result (actual) [Test] public void Test(...) { var target = TargetFactory.Create(sourceData); var actual = target.DoSomething(); Assert.AreEqual(expected, actual); }
    • Create your Test Language „The language you write test code is not the language you write your productive code.“ • Custom assertion library • Test data factory • Expressive names • One assertion per test • Cyclomatic complexity ==1 • 3 Lines rule
    • Assertion * String lenghts differ… * Expected: True but was: False Etc. Our goal is to find an error without much debugging. Let the failed test supply us with following information: 1. Which method was tested? 2. What was the intention of test? 3. What’s gone wrong exactly?
    • Assertion Let your asserst tell you the truth! Failed: Clear_removes_all_elements_from_collection Expected number of elements 0 but was 1 Expected True but was False at (0,0)
    • Factory vs Build-up Code Test Case Factories are classes which produce complex test object trees based on very few simple parameters. Simple means - simple to write & simple to read. TreeFactory.BuildTree(„a[b1,b2,b3[c1,c2,c3]]“) a b1 b2 b3 c1 c2 c3
    • Use expressive names for your tets. EXTREMELY EXPRESSIVE Create your Test Language