6. The Five Orders of Ignorance
არცოდნის 5 ხარისხი
0th Order Ignorance
რაიმეს ობიექტურად და დანამდვილებით ცოდნა
7. The Five Orders of Ignorance
არცოდნის 5 ხარისხი
0th Order Ignorance
რაიმეს ობიექტურად და დანამდვილებით ცოდნა
1st Order Ignorance
როდესაც იცი რომ არ იცი
8. The Five Orders of Ignorance
არცოდნის 5 ხარისხი
0th Order Ignorance
რაიმეს ობიექტურად და დანამდვილებით ცოდნა
1st Order Ignorance
როდესაც იცი რომ არ იცი
2nd Order Ignorance
როდესაც არ იცი რომ არ იცი
9. The Five Orders of Ignorance
არცოდნის 5 ხარისხი
0th Order Ignorance
რაიმეს ობიექტურად და დანამდვილებით ცოდნა
1st Order Ignorance
როდესაც იცი რომ არ იცი
2nd Order Ignorance
როდესაც არ იცი რომ არ იცი
3rd Order Ignorance
როდესაც ისიც კი არ იცი როგორ დაადგინო რომ არ იცი
10. The Five Orders of Ignorance
არცოდნის 5 ხარისხი
4th Order Ignorance
მაშინ როდესაც სარეთოდ წარმოდგენა არ გაქვს
Five Orders of Ignorance-ის
არცოდნის 5 ხარისხის არსებობის შესახებაც კი.
25. ტესტირების ევოლუცია
1. Automate
framework pretends to be a user
slow / flaky / corner cases not tested
2. Break down
simulate dependencies
much faster / can simulate
26. ტესტირების ევოლუცია
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
27. ტესტირების ევოლუცია
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
28. ტესტირების ევოლუცია
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
30. 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
ტესტირების ევოლუცია
32. 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
?????
35. 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:
38. 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.
46. 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
52. [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();
}
}
53. [Test]
public void TranslateOne()
{
string result = Translator.Translate(1);
Assert.That(result, Is.EqualTo("1"));
}
public static string Translate(int i)
{
return "1";
}
54. [Test]
public void TranslateTwo()
{
string result = Translator.Translate(2);
Assert.That(result, Is.EqualTo("2"));
}
public static string Translate(int i)
{
return i.ToString();
}
55. [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();
}
56. [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();
}
57. [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();
}
58. [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();
}
59. [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();
}
60. [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();
}
61. [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();
}
62. [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();
}
63. [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();
}
64. [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();
}
78. 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
79. 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);
}
80. 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
81. 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?
82. 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)
83. 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
84. Use expressive names for your tets.
EXTREMELY EXPRESSIVE
Create your Test Language