SlideShare a Scribd company logo
1 of 101
Download to read offline
Program
with GUTs
Kevlin Henney
@KevlinHenney
@kevlin@mastodon.social
@kevlin.bsky.social
threads.net/@kevlin.henney
instagram.com/kevlin.henney
about.me/kevlin
linkedin.com/in/kevlin
kevlinhenney.medium.com
kevlin@curbralan.com
slideshare.net/Kevlin
So you’re writing unit tests?
Great!
Are they any good?
Kevlin Henney
“Program with GUTs”
medium.com/97-things/program-with-guts-828e69dd8e15
Do you have GUTs?
Kevlin Henney
“Program with GUTs”
medium.com/97-things/program-with-guts-828e69dd8e15
Very many people say “TDD”
when they really mean,
“I have good unit tests”
(“I have GUTs”?)
Alistair Cockburn
“The modern programming professional has GUTs”
(“I have GUTs
Or have you landed someone
(future you?) with interest-
accumulating technical debt
in their testbase?
Kevlin Henney
“Program with GUTs”
medium.com/97-things/program-with-guts-828e69dd8e15
What do I mean by good?
Kevlin Henney
“Program with GUTs”
medium.com/97-things/program-with-guts-828e69dd8e15
We think in generalities,
but we live in detail.
Alfred North Whitehead
mastodon.social/deck/@0xabad1dea@infosec.exchange/112015426639751687
public static bool IsLeapYear(int year) 
[Test]
public void Test() 
[Test]
public void TestIsLeapYear() 
[Test]
public void TestIsLeapYearIsOK() 
[Test]
public void TestIsLeapYearIsCorrect() 
[Test]
public void TestIsLeapYearWorks() 
[Test]
public void TestIsLeapYearWorksAsExpected() 
[Test]
public void Test1() 
[Test]
public void Test2() 
[Test]
public void TestLeapYears() 
[Test]
public void TestNonLeapYears() 
[Test]
public void TestLeapYears()
{
Assert.IsTrue(IsLeapYear(2024));
Assert.IsTrue(IsLeapYear(2000));
}
[Test]
public void TestNonLeapYears() 
[Test]
public void Test2024IsALeapYear() 
[Test]
public void Test2000IsALeapYear() 
[Test]
public void Test2023IsNotALeapYear() 
[Test]
public void Test1900IsNotALeapYear() 
[Test]
public void Test2016IsALeapYear() 
[Test]
public void Test2400IsALeapYear() 
[Test]
public void Test2022IsNotALeapYear() 
[Test]
public void Test2100IsNotALeapYear() 
Write Tests
for People
Gerard Meszaros
97-things-every-x-should-know.gitbooks.io/97-things-every-programmer-should-know/content/en/thing_95
Gerard Meszaros
97-things-every-x-should-know.gitbooks.io/97-things-every-programmer-should-know/content/en/thing_95
So who should you be
writing the tests for?
For the person trying to
understand your code.
Gerard Meszaros
97-things-every-x-should-know.gitbooks.io/97-things-every-programmer-should-know/content/en/thing_95
Good tests act as
documentation for the
code they are testing.
A year divisible by 4 is a leap year
A year divisible by 400 is a leap year
A year not divisible by 4 is not a leap year
A year divisible by 100 is not a leap year
[Test] public void
A_year_divisible_by_4_is_a_leap_year() 
[Test] public void
A_year_divisible_by_400_is_a_leap_year() 
[Test] public void
A_year_not_divisible_by_4_is_not_a_leap_year() 
[Test] public void
A_year_divisible_by_100_is_not_a_leap_year() 
A_year_divisible_by_4_is_a_leap_year
A_year_divisible_by_400_is_a_leap_year
A_year_not_divisible_by_4_is_not_a_leap_year
A_year_divisible_by_100_is_not_a_leap_year
A_year_not_divisible_by_4_is_not_a_leap_year
A_year_divisible_by_4_is_a_leap_year
A_year_divisible_by_100_is_not_a_leap_year
A_year_divisible_by_400_is_a_leap_year
A_year_not_divisible_by_4_is_not_a_leap_year
A_year_divisible_by_4_but_not_by_100_is_a_leap_ye
A_year_divisible_by_100_but_not_by_400_is_not_a_l
A_year_divisible_by_400_is_a_leap_year
A_year_not_divisible_by_4_is_not_a_leap_year
A_year_divisible_by_4_but_not_by_100_is_a_leap_year
A_year_divisible_by_100_but_not_by_400_is_not_a_leap_year
A_year_divisible_by_400_is_a_leap_year
Not leap years
Leap years
Not leap years
Leap years
Not divisible by 4 Divisible by 4 Divisible by 100 Divisible by 400
IsLeapYear_YearNotDivisibleBy4_ReturnsFalse
IsLeapYear_YearDivisibleBy4ButNotBy100_ReturnsTrue
IsLeapYear_YearDivisibleBy100ButNotBy400_ReturnsFalse
IsLeapYear_YearDivisibleBy400_ReturnsTrue
A_year_not_divisible_by_4_should_not_be_a_leap_year
A_year_divisible_by_4_but_not_by_100_should_not_be_a_leap_y
A_year_divisible_by_100_but_not_by_400_should_not_be_a_leap
A_year_divisible_by_400_should_not_be_a_leap_year
A_year_not_divisible_by_4_must_not_be_a_leap_year
A_year_divisible_by_4_but_not_by_100_must_not_be_a_leap_yea
A_year_divisible_by_100_but_not_by_400_must_not_be_a_leap_y
A_year_divisible_by_400_must_not_be_a_leap_year
A_year_not_divisible_by_4_is_not_a_leap_year
A_year_divisible_by_4_but_not_by_100_is_a_leap_year
A_year_divisible_by_100_but_not_by_400_is_not_a_leap_year
A_year_divisible_by_400_is_a_leap_year
Propositions
are vehicles
for stating
how things are
or might be.
Thus only indicative
sentences which it
makes sense to think
of as being true or as
being false are
capable of expressing
propositions.
public static bool IsLeapYear(int year)
{
return year % 4 == 0 &&
year % 100 != 0 ||
year % 400 == 0;
}
A_year_not_divisible_by_4_is_not_a_leap_year
A_year_divisible_by_4_but_not_by_100_is_a_leap_year
A_year_divisible_by_100_but_not_by_400_is_not_a_leap_year
A_year_divisible_by_400_is_a_leap_year
public static bool IsLeapYear(int year)
{
return year % 4 == 0;
}
A_year_not_divisible_by_4_is_not_a_leap_year
A_year_divisible_by_4_but_not_by_100_is_a_leap_year
A_year_divisible_by_100_but_not_by_400_is_not_a_leap_year
A_year_divisible_by_400_is_a_leap_year
A failing test should tell you exactly what is
wrong quickly, without you having to spend a lot
of time analyzing the failure.
This means...
Marit van Dijk
“Use Testing to Develop Better Software Faster”
medium.com/97-things/use-testing-to-develop-better-software-faster-9dd2616543d3
Each test should test one thing.
Marit van Dijk
“Use Testing to Develop Better Software Faster”
medium.com/97-things/use-testing-to-develop-better-software-faster-9dd2616543d3
Use meaningful, descriptive names.
Don’t just describe what the test does either (we
can read the code), tell us why it does this. This
can help decide whether a test should be
updated in line with changed functionality or
whether an actual failure that should be fixed
has been found.
Marit van Dijk
“Use Testing to Develop Better Software Faster”
medium.com/97-things/use-testing-to-develop-better-software-faster-9dd2616543d3
Never trust a test you haven’t seen fail.
Marit van Dijk
“Use Testing to Develop Better Software Faster”
medium.com/97-things/use-testing-to-develop-better-software-faster-9dd2616543d3
public class Leap_year_spec
{
public class A_year_is_a_leap_year
{
[Test]
public void if_it_is_divisible_by_4_but_not_by_100() 
[Test]
public void if_it_is_divisible_by_400() 
}
public class A_year_is_not_a_leap_year
{
[Test]
public void if_it_is_not_divisible_by_4() 
[Test]
public void if_it_is_divisible_by_100_but_not_by_400() 
}
}
namespace Leap_year_spec
{
public class A_year_is_a_leap_year
{
[Test]
public void if_it_is_divisible_by_4_but_not_by_100() 
[Test]
public void if_it_is_divisible_by_400() 
}
public class A_year_is_not_a_leap_year
{
[Test]
public void if_it_is_not_divisible_by_4() 
[Test]
public void if_it_is_divisible_by_100_but_not_by_400() 
}
}
namespace Leap_year_spec
{
public class A_year_is_a_leap_year
{
[Test]
public void if_it_is_divisible_by_4_but_not_by_100() 
[Test]
public void if_it_is_divisible_by_400() 
}
public class A_year_is_not_a_leap_year
{
[Test]
public void if_it_is_not_divisible_by_4() 
[Test]
public void if_it_is_divisible_by_100_but_not_by_400() 
}
}
Nat Pryce & Steve Freeman
Are your tests really driving your development?
For tests to drive development they must do
more than just test that code performs its
required functionality: they must clearly express
that required functionality to the reader.
That is, they must be clear specifications of the
required functionality.
namespace Leap_year_spec
{
public class A_year_is_a_leap_year 
public class A_year_is_not_a_leap_year 
}
namespace Leap_year_spec
{
public class A_year_is_a_leap_year 
public class A_year_is_not_a_leap_year
{
[Test]
public void if_it_is_not_divisible_by_4()
{
Assert.IsFalse(IsLeapYear(2023));
}
[Test]
public void if_it_is_divisible_by_100_but_not_by_400() 
}
}
namespace Leap_year_spec
{
public class A_year_is_a_leap_year 
public class A_year_is_not_a_leap_year
{
[Test]
public void if_it_is_not_divisible_by_4()
{
Assert.IsFalse(IsLeapYear(2023));
Assert.IsFalse(IsLeapYear(2022));
Assert.IsFalse(IsLeapYear(1999));
Assert.IsFalse(IsLeapYear(3));
}
[Test]
public void if_it_is_divisible_by_100_but_not_by_400() 
}
}
namespace Leap_year_spec
{
public class A_year_is_a_leap_year 
public class A_year_is_not_a_leap_year
{
[TestCase(2023)]
[TestCase(2022)]
[TestCase(1999)]
[TestCase(3)]
public void if_it_is_not_divisible_by_4(int year)
{
Assert.IsFalse(IsLeapYear(year));
}
[Test]
public void if_it_is_divisible_by_100_but_not_by_400() 
}
}
namespace Leap_year_spec
{
public class A_year_is_a_leap_year 
public class A_year_is_not_a_leap_year
{
[Test]
public void if_it_is_not_divisible_by_4(
[Values(2023, 2022, 1999, 3)] int year)
{
Assert.IsFalse(IsLeapYear(year));
}
[Test]
public void if_it_is_divisible_by_100_but_not_by_400() 
}
}
namespace Leap_year_spec
{
public class A_year_is_a_leap_year
{
[Test]
public void if_it_is_divisible_by_4_but_not_by_100(
[Values(2024, 2016, 1984, 4) int year) 
[Test]
public void if_it_is_divisible_by_400(
[Range(400, 4000, 400)] int year) 
}
public class A_year_is_not_a_leap_year
{
[Test]
public void if_it_is_not_divisible_by_4(
[Values(2023, 2022, 1999, 3)] int year) 
[Test]
public void if_it_is_divisible_by_100_but_not_by_400(
[Values(2100, 1900, 1800, 100)] int year) 
}
}
Simple
cases
Common
cases
Error
cases
Boundary
cases
Simple
cases
Common
cases
Error
cases
Boundary
cases ?
namespace Leap_year_spec
{
public class A_year_is_a_leap_year 
public class A_year_is_not_a_leap_year 
public class Error_cases 
}
namespace Leap_year_spec
{
public class A_year_is_a_leap_year 
public class A_year_is_not_a_leap_year 
public class A_year_is_not_supported 
}
namespace Leap_year_spec
{
public class A_year_is_a_leap_year 
public class A_year_is_not_a_leap_year 
public class A_year_is_not_supported
{
[Test]
public void if_it_is_0()
{
Assert.Throws<ArgumentOutOfRangeException>(() => IsLeapYear(0));
}
}
}
namespace Leap_year_spec
{
public class A_year_is_a_leap_year 
public class A_year_is_not_a_leap_year 
public class A_year_is_not_supported
{
[Test]
public void if_it_is_0()
{
Assert.Catch<ArgumentOutOfRangeException>(() => IsLeapYear(0));
}
}
}
namespace Leap_year_spec
{
public class A_year_is_a_leap_year 
public class A_year_is_not_a_leap_year 
public class A_year_is_not_supported
{
[Test]
public void if_it_is_0()
{
Assert.Catch<ArgumentOutOfRangeException>(() => IsLeapYear(0));
}
[Test]
public void if_it_is_negative(
[Values(-1, -4, -100, -400)] int year)
{
Assert.Catch<ArgumentOutOfRangeException>(() => IsLeapYear(year));
}
}
}
namespace Leap_year_spec
{
public class A_year_is_a_leap_year 
public class A_year_is_not_a_leap_year 
public class A_year_is_not_supported
{
[Test]
public void if_it_is_0()
{
Assert.Catch<ArgumentOutOfRangeException>(() => IsLeapYear(0));
}
[Test]
public void if_it_is_negative(
[Values(-1, -4, -100, -400, int.MinValue)] int year)
{
Assert.Catch<ArgumentOutOfRangeException>(() => IsLeapYear(year));
}
}
}
namespace Leap_year_spec
{
public class A_year_is_a_leap_year 
public class A_year_is_not_a_leap_year 
public class A_year_is_supported 
public class A_year_is_not_supported 
}
namespace Leap_year_spec
{
public class A_year_is_a_leap_year 
public class A_year_is_not_a_leap_year 
public class A_year_is_supported
{
[Test]
public void if_it_is_positive(
[Values(1, 10000, int.MaxValue)] int year)
{
Assert.DoesNotThrow(() => IsLeapYear(year));
}
}
public class A_year_is_not_supported 
}
Leo Tolstoy
Anna Karenina
All happy families are alike;
each unhappy family is
unhappy in its own way.
namespace Leap_year_spec 
public class A_year_is_a_leap_year 
public void if_it_is_divisible_by_4_but_not_by_400() 
public void if_it_is_divisible_by_400() 
public class A_year_is_not_a_leap_year 
public void if_is_not_divisible_by_4() 
public void if_it_is_divisible_by_100_but_not_by_400() 
public class A_year_is_supported 
public void if_it_is_positive() 
public class A_year_is_not_supported 
public void if_it_is_0() 
public void if_it_is_negative() 
namespace Leap_year_spec 
public class A_year_is_a_leap_year 
public void if_it_is_divisible_by_4_but_not_by_400() 
public void if_it_is_divisible_by_400() 
public class A_year_is_not_a_leap_year 
public void if_is_not_divisible_by_4() 
public void if_it_is_divisible_by_100_but_not_by_400() 
public class A_year_is_supported 
public void if_it_is_positive() 
public class A_year_is_not_supported 
public void if_it_is_0() 
public void if_it_is_negative() 
Producer Consumer
Queue
Length
Capacity
Enqueue ⮞ ⮜ Dequeue
public class Queue<T>
{
...
public Queue(int capacity) ...
public int Capacity => ...
public int Length => ...
public bool Enqueue(T toBack) ...
public bool Dequeue(out T fromFront) ...
}
Nat Pryce & Steve Freeman
Are your tests really driving your development?
Tests that are not written with their role as
specifications in mind can be very confusing to
read. The difficulty in understanding what they
are testing can greatly reduce the velocity at
which a codebase can be changed.
public class QueueTests
{
[Test]
public void TestConstructor() ...
[Test]
public void TestCapacity() ...
[Test]
public void TestLength() ...
[Test]
public void TestEnqueue() ...
[Test]
public void TestDequeue() ...
}
public class QueueTests
{
[Test]
public void Constructor() ...
[Test]
public void Capacity() ...
[Test]
public void Length() ...
[Test]
public void Enqueue() ...
[Test]
public void Dequeue() ...
}
public class QueueTests
{
[Test]
public void CanBeConstructed() ...
[Test]
public void HasCapacity() ...
[Test]
public void HasLength() ...
[Test]
public void CanBeEnqueuedOn() ...
[Test]
public void CanBeDequeuedFrom() ...
}
public class QueueTests
{
[Test]
public void CanSometimesBeConstructed() ...
[Test]
public void HasCapacity() ...
[Test]
public void HasLength() ...
[Test]
public void CanSometimesBeEnqueuedOn() ...
[Test]
public void CanSometimesBeDequeuedFrom() ...
}
85
twitter.com/venkat_s/status/1633131055635890179
namespace Queue_spec 
public class Creating_a_queue 
public void leaves_it_empty() 
public void preserves_positive_bounding_capacity() 
public void fails_with_non_positive_bounding_capacity() 
public class Enqueuing_on 
public void an_empty_queue_makes_it_longer() 
public void a_non_empty_queue_makes_it_longer() 
public void a_non_full_queue_up_to_capacity_makes_it_full() 
public void a_full_queue_is_ignored() 
public class Dequeuing_from 
public void an_empty_queue_is_ignored_with_default_value() 
public void a_non_empty_queue_gives_values_in_order_enqueued() 
public void a_full_queue_makes_it_non_full() 
namespace Queue_spec 
public class Creating_a_queue 
public void leaves_it_empty() 
public void preserves_positive_bounding_capacity() 
public void fails_with_non_positive_bounding_capacity() 
public class Enqueuing_on 
public void an_empty_queue_makes_it_longer() 
public void a_non_empty_queue_makes_it_longer() 
public void a_non_full_queue_up_to_capacity_makes_it_full() 
public void a_full_queue_is_ignored() 
public class Dequeuing_from 
public void an_empty_queue_is_ignored_with_default_value() 
public void a_non_empty_queue_gives_values_in_order_enqueued() 
public void a_full_queue_makes_it_non_full() 
public class Enqueuing_on 
public void an_empty_queue_makes_it_longer(string value)
{
var queue = new Queue<string>(2);
var enqueued = queue.Enqueue(value);
Assert.IsTrue(enqueued);
Assert.AreEqual(1, queue.Length);
}
public class Enqueuing_on 
public void an_empty_queue_makes_it_longer(string value)
{
var queue = new Queue<string>(2);
var enqueued = queue.Enqueue(value);
Assert.IsTrue(enqueued);
Assert.AreEqual(1, queue.Length);
}
Gerard Meszaros
97-things-every-x-should-know.gitbooks.io/97-things-every-programmer-should-know/content/en/thing_95
For each usage scenario, the test(s):
▪ Describe the context, starting point, or
preconditions that must be satisfied
▪ Illustrate how the software is invoked
▪ Describe the expected results or
postconditions to be verified
public class Enqueuing_on 
public void an_empty_queue_makes_it_longer(string value)
{
// Arrange:
var queue = new Queue<string>(2);
// Act:
var enqueued = queue.Enqueue(value);
// Assert:
Assert.IsTrue(enqueued);
Assert.AreEqual(1, queue.Length);
}
public class Enqueuing_on 
public void an_empty_queue_makes_it_longer(string value)
{
// Establish precondition for operation:
var queue = new Queue<string>(2);
// Perform operation of interest:
var enqueued = queue.Enqueue(value);
// Confirm postcondition of operation:
Assert.IsTrue(enqueued);
Assert.AreEqual(1, queue.Length);
}
public class Enqueuing_on 
public void an_empty_queue_makes_it_longer(string value)
{
// Given:
var queue = new Queue<string>(2);
// When:
var enqueued = queue.Enqueue(value);
// Then:
Assert.IsTrue(enqueued);
Assert.AreEqual(1, queue.Length);
}
Thinking in States
In most real-world situations, people’s
relaxed attitude to state is not an issue.
Unfortunately, however, many
programmers are quite vague about
state too — and that is a problem.
Niclas Nilsson
97-things-every-x-should-know.gitbooks.io/97-things-every-programmer-should-know/content/en/thing_84
Non-Empty
Empty
Dequeue Enqueue
Dequeue [Length > 1]
Enqueue
Dequeue [Length == 1]
new [Capacity > 0]
Non-Full
Empty
Dequeue
Enqueue
Dequeue [Length > 1]
Enqueue
Dequeue [Length == 1]
new [Capacity > 0]
Full
Non-Empty
[Length = Capacity]
[Length < Capacity]
namespace Queue_spec 
public class A_new_queue 
public void is_empty() 
public void preserves_positive_bounding_capacity() 
public void fails_with_non_positive_bounding_capacity() 
public class An_empty_queue 
public void ignores_dequeuing_with_default_value() 
public void becomes_non_empty_when_value_enqueued() 
public class A_non_empty_queue 
public class that_is_not_full 
public void becomes_longer_when_value_enqueued() 
public void becomes_full_when_enqueued_up_to_capacity() 
public class that_is_full 
public void ignores_further_enqueued_values() 
public void becomes_non_full_when_dequeued() 
public void dequeues_values_in_order_enqueued() 
namespace Queue_spec 
public class A_new_queue 
public void is_empty() 
public void preserves_positive_bounding_capacity() 
public void fails_with_non_positive_bounding_capacity() 
public class An_empty_queue 
public void ignores_dequeuing_with_default_value() 
public void becomes_non_empty_when_value_enqueued() 
public class A_non_empty_queue 
public class that_is_not_full 
public void becomes_longer_when_value_enqueued() 
public void becomes_full_when_enqueued_up_to_capacity() 
public class that_is_full 
public void ignores_further_enqueued_values() 
public void becomes_non_full_when_dequeued() 
public void dequeues_values_in_order_enqueued() 
Given
When
Then
Given can be used to group
tests for operations with
respect to common
initial state
When can be used to group
tests by operation,
differentiated by initial
state or outcome
Then can be used to group
tests by common
outcome, regardless of
initial state
I hope that’s been useful.
You’re off to do revisit some
tests?
OK, catch you later.
Kevlin Henney
“Program with GUTs”
medium.com/97-things/program-with-guts-828e69dd8e15

More Related Content

Similar to Program with GUTs

Practical A/B Testing Statistics: 5 Tips To Help You Get Reliable Data
Practical A/B Testing Statistics: 5 Tips To Help You Get Reliable DataPractical A/B Testing Statistics: 5 Tips To Help You Get Reliable Data
Practical A/B Testing Statistics: 5 Tips To Help You Get Reliable DataHanapin Marketing
 
What's the SCORE? - how to make sense of a business change
What's the SCORE? - how to make sense of a business changeWhat's the SCORE? - how to make sense of a business change
What's the SCORE? - how to make sense of a business changeTetradian Consulting
 
Points 200Term Paper Using Agile Project Management to Impleme.docx
Points 200Term Paper Using Agile Project Management to Impleme.docxPoints 200Term Paper Using Agile Project Management to Impleme.docx
Points 200Term Paper Using Agile Project Management to Impleme.docxharrisonhoward80223
 
Your Tests are Lying to You - Improving your Testing by Testing What Really M...
Your Tests are Lying to You - Improving your Testing by Testing What Really M...Your Tests are Lying to You - Improving your Testing by Testing What Really M...
Your Tests are Lying to You - Improving your Testing by Testing What Really M...Brian Childress
 
Key Test Design Techniques
Key Test Design TechniquesKey Test Design Techniques
Key Test Design TechniquesTechWell
 
Practical Machine Learning
Practical Machine LearningPractical Machine Learning
Practical Machine LearningVu Pham
 
An Introduction to Saville Comprehension Aptitude
An Introduction to Saville Comprehension Aptitude An Introduction to Saville Comprehension Aptitude
An Introduction to Saville Comprehension Aptitude JobTestPrep
 
Simpler Machine Learning with SKLL
Simpler Machine Learning with SKLLSimpler Machine Learning with SKLL
Simpler Machine Learning with SKLLDaniel Blanchard
 
Points 100Assignment 3 Presentation of Leadership and Manageme.docx
Points 100Assignment 3 Presentation of Leadership and Manageme.docxPoints 100Assignment 3 Presentation of Leadership and Manageme.docx
Points 100Assignment 3 Presentation of Leadership and Manageme.docxLeilaniPoolsy
 
Chapter 4( standardized testing)
Chapter 4( standardized testing)Chapter 4( standardized testing)
Chapter 4( standardized testing)Kheang Sokheng
 
Lead Time: What We Know About It...
Lead Time: What We Know About It...Lead Time: What We Know About It...
Lead Time: What We Know About It...azheglov
 
Getting Roi Numbers From Ut Des Moines10 Sept09
Getting Roi Numbers From Ut Des Moines10 Sept09Getting Roi Numbers From Ut Des Moines10 Sept09
Getting Roi Numbers From Ut Des Moines10 Sept09John Sorflaten, PhD, CUXP
 
Practical Machine Learning and Rails Part2
Practical Machine Learning and Rails Part2Practical Machine Learning and Rails Part2
Practical Machine Learning and Rails Part2ryanstout
 
Agile Testing - Testing from Day 1
Agile Testing - Testing from Day 1Agile Testing - Testing from Day 1
Agile Testing - Testing from Day 1Fadi Stephan
 
Software testing with examples in Angular (and AngularJS)
Software testing with examples in Angular (and AngularJS)Software testing with examples in Angular (and AngularJS)
Software testing with examples in Angular (and AngularJS)Paweł Żurowski
 
The Three Pillars Approach to an Agile Testing Strategy
The Three Pillars Approach to an Agile Testing StrategyThe Three Pillars Approach to an Agile Testing Strategy
The Three Pillars Approach to an Agile Testing StrategyTechWell
 
Continuous Delivery: Delivering Client Value at Light Speed - DevCon 2015
Continuous Delivery: Delivering Client Value at Light Speed - DevCon 2015Continuous Delivery: Delivering Client Value at Light Speed - DevCon 2015
Continuous Delivery: Delivering Client Value at Light Speed - DevCon 2015Aaron Blythe
 

Similar to Program with GUTs (20)

Practical A/B Testing Statistics: 5 Tips To Help You Get Reliable Data
Practical A/B Testing Statistics: 5 Tips To Help You Get Reliable DataPractical A/B Testing Statistics: 5 Tips To Help You Get Reliable Data
Practical A/B Testing Statistics: 5 Tips To Help You Get Reliable Data
 
What's the SCORE? - how to make sense of a business change
What's the SCORE? - how to make sense of a business changeWhat's the SCORE? - how to make sense of a business change
What's the SCORE? - how to make sense of a business change
 
Points 200Term Paper Using Agile Project Management to Impleme.docx
Points 200Term Paper Using Agile Project Management to Impleme.docxPoints 200Term Paper Using Agile Project Management to Impleme.docx
Points 200Term Paper Using Agile Project Management to Impleme.docx
 
Your Tests are Lying to You - Improving your Testing by Testing What Really M...
Your Tests are Lying to You - Improving your Testing by Testing What Really M...Your Tests are Lying to You - Improving your Testing by Testing What Really M...
Your Tests are Lying to You - Improving your Testing by Testing What Really M...
 
Key Test Design Techniques
Key Test Design TechniquesKey Test Design Techniques
Key Test Design Techniques
 
Practical Machine Learning
Practical Machine LearningPractical Machine Learning
Practical Machine Learning
 
An Introduction to Saville Comprehension Aptitude
An Introduction to Saville Comprehension Aptitude An Introduction to Saville Comprehension Aptitude
An Introduction to Saville Comprehension Aptitude
 
Simpler Machine Learning with SKLL
Simpler Machine Learning with SKLLSimpler Machine Learning with SKLL
Simpler Machine Learning with SKLL
 
FS 5 - Episode 5
FS 5 - Episode 5FS 5 - Episode 5
FS 5 - Episode 5
 
FS 5 - Episode 5
FS 5 - Episode 5FS 5 - Episode 5
FS 5 - Episode 5
 
Points 100Assignment 3 Presentation of Leadership and Manageme.docx
Points 100Assignment 3 Presentation of Leadership and Manageme.docxPoints 100Assignment 3 Presentation of Leadership and Manageme.docx
Points 100Assignment 3 Presentation of Leadership and Manageme.docx
 
Best CAT & MAT Coaching In Kolkata - Sagar Sir Coaching
Best CAT & MAT Coaching In Kolkata - Sagar Sir CoachingBest CAT & MAT Coaching In Kolkata - Sagar Sir Coaching
Best CAT & MAT Coaching In Kolkata - Sagar Sir Coaching
 
Chapter 4( standardized testing)
Chapter 4( standardized testing)Chapter 4( standardized testing)
Chapter 4( standardized testing)
 
Lead Time: What We Know About It...
Lead Time: What We Know About It...Lead Time: What We Know About It...
Lead Time: What We Know About It...
 
Getting Roi Numbers From Ut Des Moines10 Sept09
Getting Roi Numbers From Ut Des Moines10 Sept09Getting Roi Numbers From Ut Des Moines10 Sept09
Getting Roi Numbers From Ut Des Moines10 Sept09
 
Practical Machine Learning and Rails Part2
Practical Machine Learning and Rails Part2Practical Machine Learning and Rails Part2
Practical Machine Learning and Rails Part2
 
Agile Testing - Testing from Day 1
Agile Testing - Testing from Day 1Agile Testing - Testing from Day 1
Agile Testing - Testing from Day 1
 
Software testing with examples in Angular (and AngularJS)
Software testing with examples in Angular (and AngularJS)Software testing with examples in Angular (and AngularJS)
Software testing with examples in Angular (and AngularJS)
 
The Three Pillars Approach to an Agile Testing Strategy
The Three Pillars Approach to an Agile Testing StrategyThe Three Pillars Approach to an Agile Testing Strategy
The Three Pillars Approach to an Agile Testing Strategy
 
Continuous Delivery: Delivering Client Value at Light Speed - DevCon 2015
Continuous Delivery: Delivering Client Value at Light Speed - DevCon 2015Continuous Delivery: Delivering Client Value at Light Speed - DevCon 2015
Continuous Delivery: Delivering Client Value at Light Speed - DevCon 2015
 

More from Kevlin Henney

The Case for Technical Excellence
The Case for Technical ExcellenceThe Case for Technical Excellence
The Case for Technical ExcellenceKevlin Henney
 
Empirical Development
Empirical DevelopmentEmpirical Development
Empirical DevelopmentKevlin Henney
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that LetterKevlin Henney
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that LetterKevlin Henney
 
Solid Deconstruction
Solid DeconstructionSolid Deconstruction
Solid DeconstructionKevlin Henney
 
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went AwayProcedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went AwayKevlin Henney
 
Refactoring to Immutability
Refactoring to ImmutabilityRefactoring to Immutability
Refactoring to ImmutabilityKevlin Henney
 
Turning Development Outside-In
Turning Development Outside-InTurning Development Outside-In
Turning Development Outside-InKevlin Henney
 
Giving Code a Good Name
Giving Code a Good NameGiving Code a Good Name
Giving Code a Good NameKevlin Henney
 
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...Kevlin Henney
 
Thinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation QuadrantThinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation QuadrantKevlin Henney
 
The Error of Our Ways
The Error of Our WaysThe Error of Our Ways
The Error of Our WaysKevlin Henney
 
Seven Ineffective Coding Habits of Many Programmers
Seven Ineffective Coding Habits of Many ProgrammersSeven Ineffective Coding Habits of Many Programmers
Seven Ineffective Coding Habits of Many ProgrammersKevlin Henney
 

More from Kevlin Henney (20)

The Case for Technical Excellence
The Case for Technical ExcellenceThe Case for Technical Excellence
The Case for Technical Excellence
 
Empirical Development
Empirical DevelopmentEmpirical Development
Empirical Development
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
 
Solid Deconstruction
Solid DeconstructionSolid Deconstruction
Solid Deconstruction
 
Get Kata
Get KataGet Kata
Get Kata
 
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went AwayProcedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
 
Agility ≠ Speed
Agility ≠ SpeedAgility ≠ Speed
Agility ≠ Speed
 
Refactoring to Immutability
Refactoring to ImmutabilityRefactoring to Immutability
Refactoring to Immutability
 
Old Is the New New
Old Is the New NewOld Is the New New
Old Is the New New
 
Turning Development Outside-In
Turning Development Outside-InTurning Development Outside-In
Turning Development Outside-In
 
Giving Code a Good Name
Giving Code a Good NameGiving Code a Good Name
Giving Code a Good Name
 
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
 
Thinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation QuadrantThinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation Quadrant
 
Code as Risk
Code as RiskCode as Risk
Code as Risk
 
Software Is Details
Software Is DetailsSoftware Is Details
Software Is Details
 
Game of Sprints
Game of SprintsGame of Sprints
Game of Sprints
 
Good Code
Good CodeGood Code
Good Code
 
The Error of Our Ways
The Error of Our WaysThe Error of Our Ways
The Error of Our Ways
 
Seven Ineffective Coding Habits of Many Programmers
Seven Ineffective Coding Habits of Many ProgrammersSeven Ineffective Coding Habits of Many Programmers
Seven Ineffective Coding Habits of Many Programmers
 

Recently uploaded

How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationBradBedford3
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Mater
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...OnePlan Solutions
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in NoidaBuds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in Noidabntitsolutionsrishis
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesŁukasz Chruściel
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Angel Borroy López
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceBrainSell Technologies
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Natan Silnitsky
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Cizo Technology Services
 
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfStefano Stabellini
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commercemanigoyal112
 

Recently uploaded (20)

How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion Application
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in NoidaBuds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New Features
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. Salesforce
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
 
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdf
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commerce
 

Program with GUTs