SlideShare une entreprise Scribd logo
1  sur  61
{
A Test of Strength
ACCU Conference 2017
Chris Oldwood
{Optimising for writing
The Wrong Goal
Tests That Fit in Your Head
https://flic.kr/p/kLgf7V
https://www.amazon.com/Steve-Maguire/e/B00DP4BEB2
A Watershed Moment
Node ParseXmlNode()
{
- return ToNode(ReadTag());
+ return ToNode(Decode(ReadTag()));
class MoneyTest : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE( MoneyTest );
...
CPPUNIT_TEST( testAdd );
...
CPPUNIT_TEST_SUITE_END();
};
void MoneyTest::testAdd()
{
const Money money12FF( 12, "FF" );
const Money expectedMoney( 135, "FF" );
Money money( 123, "FF" );
money += money12FF;
CPPUNIT_ASSERT( expectedMoney == money );
CPPUNIT_ASSERT( &money == &(money += money12FF) );
}
“Premature optimization is the root of all
evil.” -- Tony Hoare
“You can prematurely optimize maintainability,
flexibility, security, and robustness just like you
can performance.” -- John Carmack
https://en.wikipedia.org/wiki/John_Carmack
https://en.wikipedia.org/wiki/Tony_Hoare
{
Core::CmdLineParser oParser(s_aoSwitches, s_aoSwitches+s_nCount);
TEST_TRUE(oParser.GetNamedArgs().empty() && oParser.GetUnnamedArgs().empty());
static tchar* argv[] = { TXT("program.exe"), TXT("-short"), TXT("/short"),
TXT("--long"), TXT("/long"), TXT("-b"), TXT("--both"),
TXT("/both"), TXT("unnamed") };
static int argc = ARRAY_SIZE(argv);
oParser.Parse(argc, argv);
TEST_TRUE(oParser.GetNamedArgs().size() == 3);
TEST_TRUE(oParser.GetUnnamedArgs().size() == 1);
TEST_TRUE(oParser.IsSwitchSet(SHORT_ONLY) && oParser.IsSwitchSet(LONG_ONLY)
&& oParser.IsSwitchSet(SHORT_LONG));
TEST_TRUE(!oParser.IsSwitchSet(FLAG));
static tchar* argv2[] = { TXT("program.exe") };
static int argc2 = ARRAY_SIZE(argv2);
oParser.Parse(argc2, argv2);
TEST_TRUE(oParser.GetNamedArgs().empty() && oParser.GetUnnamedArgs().empty());
}
WTFs (Weak Test Functions)
http://www.osnews.com/story/19266/WTFs_m
 Multiple responsibilities
 No clear intent
 Noise from incidental details
 Observing using side-effects
 Under or overly prescriptive
 Non-deterministic
 Unmanaged resources
Common Smells of WTFs
{Playing the long game
Towards a Better Goal
Essential Redundancy
https://twitter.com/jbrains/status/167297606698008576
https://www.amazon.co.uk/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052
Design for Testability
https://flic.kr/p/aXBw2i
First Class Citizens
https://flic.kr/p/iHwQGJ
Mutation Testing
https://flic.kr/p/5Gc5h4
Behaviours, Not Methods
https://flic.kr/p/n6miW6
Executable Specifications
https://flic.kr/p/eaQywa https://flic.kr/p/rzVfcR
Cope vs. Bob
http://blog.jayway.com/wp-content/uploads/2009/05/Picture-883.png
https://images-na.ssl-images-amazon.com/images/I/61b7VTCUEfL._UX250_.jpg
The Testing Polygon
Customer Tests
Programmer Tests
A Test of Strength
#include <the_world>
{Writing stronger tests
In Practice
“Naming is hard. Really hard. You
just won’t believe how vastly,
hugely, mind-bogglingly hard it
is.” -- Adam Douglas
Struggling to name a test is a sign
that you don’t know what you’re
doing. Listen to that feedback.
Break The Rules
public class client_automatically_reconnects
{
public class given_the_service_is_already_running
{
. . .
}
public class when_the_connection_is_lost : connected
{
public void then_it_logs_a_disconnect_event()
{
. . .
}
public void then_it_reconnects_in_the_background()
{
. . .
}
}
}
public static class client_automatically_reconnects
{
public static class so_the_service_is_happily_running
{
public static void then_the_connection_is_lost()
{
"so it logs a disconnect event".Is(() =>
{
// . . .
}),
"and it reconnects in the background".Is(() =>
{
// . . .
}),
});
}
}
Debugging Using Language
[Test]
public void write_returns_success_for_good_data()
{
var data = CreateGoodData();
var indicator = Write(data);
Assert.True(indicator);
}
[Test]
public void write_returns_failure_for_bad_data()
{
var data = CreateBadData();
var indicator = Write(data);
Assert.True(indicator);
}
Describe Scenarios
[TestCase("", false)]
[TestCase("12345", true)]
[TestCase("!abc.def?", true)]
[TestCase("(abc) [def]", false)]
public void only_valid_input_accepted(...)
{
Assert.That(Input.IsValid(input), Is.EqualTo(valid));
}
const bool Empty_not_valid = false;
const bool Numbers_are_valid = true;
const bool Punctuation_allowed = true;
const bool Whitespace_is_invalid = false;
[TestCase("", Empty_not_valid)]
[TestCase("12345", Numbers_are_valid)]
[TestCase("!abc.def?", Punctuation_allowed)]
[TestCase("(abc) [def]", Whitespace_is_invalid)]
public void only_valid_input_accepted(...)
{
Assert.That(Input.IsValid(input), Is.EqualTo(valid));
}
[TestCase("", false, "Cannot be empty")]
[TestCase("12345", true, "Numbers are valid")]
[TestCase("!abc.def?", true, "Punctuation is allowed")]
[TestCase("(abc) [def]", false, "Whitespace invalid")]
public void only_valid_input_accepted(...)
{
Assert.That(Input.IsValid(input),
Is.EqualTo(valid), message);
}
[Test]
public void sending_throws_when_service_unavailable()
{
MockRestApi.RespondWith = () =>
{
return new HttpResponse{ StatusCode = 500 };
};
var client = new RestClient();
Assert.That(() => client.SendRequest(),
Throws.Exception);
}
[Test]
public void sending_throws_on_server_error()
{
var any5xxStatusCode = 500;
MockRestApi.RespondWith = () =>
{
return new HttpResponse
{ StatusCode = any5xxStatusCode };
};
var client = new RestClient();
Assert.That(() => client.SendRequest(),
Throws.Exception);
}
One Behaviour Per Test
[Test]
public void calculates_the_result()
{
// . . .
Assert.That(result, Is.EqualTo(...));
Assert.That(log.Messages,
Contains.Substring("the calculation took"));
}
[Test]
public void runs_and_instruments_the_calculation()
{
// . . .
Assert.That(result, Is.EqualTo(...));
Assert.That(log.Messages,
Contains.Substring("the calculation took"));
}
[Test]
public void calculates_the_result()
{
// . . .
Assert.That(result, Is.EqualTo(...));
}
[Test]
public void instruments_the_calculation()
{
// . . .
Assert.That(log.Messages,
Contains.Substring("the calculation took"));
}
public class Result<S, E>
{
public Option<S> Success { get; }
public Option<E> Error { get; }
}
[Test]
public void fetching_data_returns_latest_value()
{
var result = SendRequest(...);
Assert.That(result.Success.HasValue, Is.True);
Assert.That(result.Error.HasValue, Is.False);
Assert.That(result.Success.Value, Is.EqualTo(...));
}
Tautologies
[Test]
public void abs_returns_magnitude_of_the_value()
{
const int negativeValue = -1;
var result = Math.Abs(negativeValue);
Assert.That(result, Is.EqualTo(Math.Abs(-1)));
}
[Test]
public void id_generated_during_processing()
{
var expected = Formatter.Format();
var component = new Component();
var result = component.Process();
Assert.That(result.Id, Is.EqualTo(expected));
}
. . .
public class Component
{
public Result Process()
{
var id = Formatter.Format();
[Test]
public void id_generated_during_processing()
{
var component = new Component();
var result = component.Process();
Assert.That(result.Id, Is.Not.Empty);
}
[Test]
public void unique_id_generated_during_processing()
{
const string uniqueId = “unique-id";
GuidGenerator.Implementation = () =>
{
return uniqueId;
};
var component = new Component();
var result = component.Process();
Assert.That(result.Id, Contains.Substring(uniqueId));
}
Overly-Prescriptive
[Test]
public void id_generated_during_processing()
{
DateTime timestamp = new DateTime(2001,3,4,5,6,7);
Clock.NowImpl = () => { return timestamp; };
var component = new Component();
var result = component.Process();
Assert.That(result.Id,
Is.EqualTo("id-20010304-050607"));
}
[Test]
public void id_generated_during_processing()
{
DateTime timestamp = new DateTime(2001,3,4,5,6,7);
Clock.NowImpl = () => { return timestamp; };
var component = new Component();
var result = component.Process();
Assert.That(result.Id,
Does.Contain(timestamp.Year.ToString())
.And.Contains(timestamp.Month.ToString())
.And.Contains(timestamp.Day.ToString()));
}
Relying on Side Effects
[Test]
public void refreshes_cache()
{
var log = new InMemoryLog();
Log.Logger = log;
Action.Do();
Assert.That(log.Messages,
Does.Contain("Refreshed cache"));
}
public interface ICache
{
void Refresh();
}
public class MockCache : ICache
{
public bool Refreshed = false;
public void Refresh()
{
Refreshed = true;
}
}
[Test]
public void refreshes_cache()
{
var cache = new MockCache();
Action.Do(cache);
Assert.True(cache.Refreshed);
}
Non-Deterministic Tests
[Test]
public void records_the_current_time()
{
var result = Action.Do();
Assert.That(result.Timestamp,
Is.EqualTo(DateTime.Now));
}
public interface IClock
{
DateTime Now { get; }
}
public class FixedClock : IClock
{
public FixedClock(DateTime now)
{
_now = now;
}
public DateTime Now
{
get { return _now; }
}
private readonly DateTime _now;
}
public static class Clock
{
public static DateTime Now
{
get { return Implementation(); }
}
internal static Func<DateTime> Implementation = () =>
{
return DateTime.Now;
};
}
[Test]
public void records_the_current_time ()
{
DateTime timestamp = new DateTime(. . .);
Clock.Implementation = () => { return timestamp; };
var result = Action.Do();
Assert.That(result.Timestamp,
Is.EqualTo(timestamp));
}
Unmanaged Resources
public class Cache
{
public Cache()
{
new Thread(() =>
{
...
});
}
}
public class Cache : IDisposable
{
public Cache()
{
backgroundThread = new Thread(() =>
{
...
});
}
public void Dispose()
{
backgroundThread?.Join();
backgroundThread = null;
}
private readonly Thread backgroundThread;
}
public class Cache
{
public void Refresh()
{
...
}
}
public class AutoRefreshingCache
{
public AutoRefreshingCache()
{
backgroundThread = new Thread . . .
}
private readonly Cache = new Cache();
private readonly Thread backgroundThread;
}
Sync, Not Sleep
[Test]
public void event_logged_when_refreshed()
{
var log = new InMemoryLog();
Log.Logger = log;
var cache = new Cache();
Thread.Sleep(5000);
Assert.That(log.Messages,
Does.Contain("Refreshed cache"));
}
[Test]
public void event_logged_when_refreshed()
{
var log = new InMemoryLog();
Log.Logger = log;
var invoked = new ManualResetEvent(false);
var connection = new MockConnection(invoked);
var cache = new Cache(connection);
invoked.WaitOne(10000);
Assert.That(log.Messages,
Does.Contain("Refreshed cache"));
}
{Strength to deliver
Testing Times
Courage
https://www.amazon.co.uk/Extreme-Programming-Explained-Embrace-Change/dp/0321278658
Assert.True(TheEnd);
Blog:
http://chrisoldwood.blogspot.co.uk
Articles:
http://chrisoldwood.com/articles.htm

Contenu connexe

Tendances

Dealing with Legacy PHP Applications
Dealing with Legacy PHP ApplicationsDealing with Legacy PHP Applications
Dealing with Legacy PHP Applications
Clinton Dreisbach
 
생산적인 개발을 위한 지속적인 테스트
생산적인 개발을 위한 지속적인 테스트생산적인 개발을 위한 지속적인 테스트
생산적인 개발을 위한 지속적인 테스트
기룡 남
 

Tendances (18)

PVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesPVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error Examples
 
What’s new in C# 6
What’s new in C# 6What’s new in C# 6
What’s new in C# 6
 
The secret unit testing tools no one has ever told you about
The secret unit testing tools no one has ever told you aboutThe secret unit testing tools no one has ever told you about
The secret unit testing tools no one has ever told you about
 
Hidden rocks in Oracle ADF
Hidden rocks in Oracle ADFHidden rocks in Oracle ADF
Hidden rocks in Oracle ADF
 
How Data Flow analysis works in a static code analyzer
How Data Flow analysis works in a static code analyzerHow Data Flow analysis works in a static code analyzer
How Data Flow analysis works in a static code analyzer
 
Dealing with Legacy PHP Applications
Dealing with Legacy PHP ApplicationsDealing with Legacy PHP Applications
Dealing with Legacy PHP Applications
 
Easy Button
Easy ButtonEasy Button
Easy Button
 
Using Change Streams to Keep Up with Your Data
Using Change Streams to Keep Up with Your DataUsing Change Streams to Keep Up with Your Data
Using Change Streams to Keep Up with Your Data
 
Asynchronous JS in Odoo
Asynchronous JS in OdooAsynchronous JS in Odoo
Asynchronous JS in Odoo
 
How to implement g rpc services in nodejs
How to implement g rpc services in nodejsHow to implement g rpc services in nodejs
How to implement g rpc services in nodejs
 
computer project code ''payroll'' (based on datafile handling)
computer project code ''payroll'' (based on datafile handling)computer project code ''payroll'' (based on datafile handling)
computer project code ''payroll'' (based on datafile handling)
 
From typing the test to testing the type
From typing the test to testing the typeFrom typing the test to testing the type
From typing the test to testing the type
 
Impact of the New ORM on Your Modules
Impact of the New ORM on Your ModulesImpact of the New ORM on Your Modules
Impact of the New ORM on Your Modules
 
생산적인 개발을 위한 지속적인 테스트
생산적인 개발을 위한 지속적인 테스트생산적인 개발을 위한 지속적인 테스트
생산적인 개발을 위한 지속적인 테스트
 
React table tutorial project setup, use table, and usefilter
React table tutorial project setup, use table, and usefilterReact table tutorial project setup, use table, and usefilter
React table tutorial project setup, use table, and usefilter
 
JavaScript Proxy (ES6)
JavaScript Proxy (ES6)JavaScript Proxy (ES6)
JavaScript Proxy (ES6)
 
MaintainStaffTable
MaintainStaffTableMaintainStaffTable
MaintainStaffTable
 
Bad test, good test
Bad test, good testBad test, good test
Bad test, good test
 

Similaire à A Test of Strength

Solve the coding errors for upvotemake test-statsg++ -g -std=c++.pdf
Solve the coding errors for upvotemake test-statsg++ -g -std=c++.pdfSolve the coding errors for upvotemake test-statsg++ -g -std=c++.pdf
Solve the coding errors for upvotemake test-statsg++ -g -std=c++.pdf
snewfashion
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests
Tomek Kaczanowski
 
C-Sharp Arithmatic Expression Calculator
C-Sharp Arithmatic Expression CalculatorC-Sharp Arithmatic Expression Calculator
C-Sharp Arithmatic Expression Calculator
Neeraj Kaushik
 

Similaire à A Test of Strength (20)

How to write clean tests
How to write clean testsHow to write clean tests
How to write clean tests
 
Understanding JavaScript Testing
Understanding JavaScript TestingUnderstanding JavaScript Testing
Understanding JavaScript Testing
 
2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests
 
Testing, Performance Analysis, and jQuery 1.4
Testing, Performance Analysis, and jQuery 1.4Testing, Performance Analysis, and jQuery 1.4
Testing, Performance Analysis, and jQuery 1.4
 
Solve the coding errors for upvotemake test-statsg++ -g -std=c++.pdf
Solve the coding errors for upvotemake test-statsg++ -g -std=c++.pdfSolve the coding errors for upvotemake test-statsg++ -g -std=c++.pdf
Solve the coding errors for upvotemake test-statsg++ -g -std=c++.pdf
 
code for quiz in my sql
code for quiz  in my sql code for quiz  in my sql
code for quiz in my sql
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests
 
Testing javascript in the frontend
Testing javascript in the frontendTesting javascript in the frontend
Testing javascript in the frontend
 
Conf soat tests_unitaires_Mockito_jUnit_170113
Conf soat tests_unitaires_Mockito_jUnit_170113Conf soat tests_unitaires_Mockito_jUnit_170113
Conf soat tests_unitaires_Mockito_jUnit_170113
 
C-Sharp Arithmatic Expression Calculator
C-Sharp Arithmatic Expression CalculatorC-Sharp Arithmatic Expression Calculator
C-Sharp Arithmatic Expression Calculator
 
Best practices unit testing
Best practices unit testing Best practices unit testing
Best practices unit testing
 
Apache Commons - Don\'t re-invent the wheel
Apache Commons - Don\'t re-invent the wheelApache Commons - Don\'t re-invent the wheel
Apache Commons - Don\'t re-invent the wheel
 
ES2015 New Features
ES2015 New FeaturesES2015 New Features
ES2015 New Features
 
What We Talk About When We Talk About Unit Testing
What We Talk About When We Talk About Unit TestingWhat We Talk About When We Talk About Unit Testing
What We Talk About When We Talk About Unit Testing
 
Test driven node.js
Test driven node.jsTest driven node.js
Test driven node.js
 
Writing testable js [by Ted Piotrowski]
Writing testable js [by Ted Piotrowski]Writing testable js [by Ted Piotrowski]
Writing testable js [by Ted Piotrowski]
 
Stop Making Excuses and Start Testing Your JavaScript
Stop Making Excuses and Start Testing Your JavaScriptStop Making Excuses and Start Testing Your JavaScript
Stop Making Excuses and Start Testing Your JavaScript
 
Jakarta Commons - Don't re-invent the wheel
Jakarta Commons - Don't re-invent the wheelJakarta Commons - Don't re-invent the wheel
Jakarta Commons - Don't re-invent the wheel
 
Google guava
Google guavaGoogle guava
Google guava
 
Test driven development_for_php
Test driven development_for_phpTest driven development_for_php
Test driven development_for_php
 

Plus de Chris Oldwood

Plus de Chris Oldwood (16)

The __far* Side
The __far* SideThe __far* Side
The __far* Side
 
Monolithic Delivery
Monolithic DeliveryMonolithic Delivery
Monolithic Delivery
 
In The Toolbox - LIVE!
In The Toolbox - LIVE!In The Toolbox - LIVE!
In The Toolbox - LIVE!
 
Test-Driven SQL
Test-Driven SQLTest-Driven SQL
Test-Driven SQL
 
Waltzing with Branches [ACCU]
Waltzing with Branches [ACCU]Waltzing with Branches [ACCU]
Waltzing with Branches [ACCU]
 
Continuous Delivery
Continuous DeliveryContinuous Delivery
Continuous Delivery
 
Becoming a Bitter Programmer
Becoming a Bitter ProgrammerBecoming a Bitter Programmer
Becoming a Bitter Programmer
 
Waltzing with Branches [Agile o/t Beach]
Waltzing with Branches [Agile o/t Beach]Waltzing with Branches [Agile o/t Beach]
Waltzing with Branches [Agile o/t Beach]
 
Using xUnit as a Swiss-Aarmy Testing Toolkit
Using xUnit as a Swiss-Aarmy Testing ToolkitUsing xUnit as a Swiss-Aarmy Testing Toolkit
Using xUnit as a Swiss-Aarmy Testing Toolkit
 
xUnit Style Database Testing
xUnit Style Database TestingxUnit Style Database Testing
xUnit Style Database Testing
 
Robust Software
Robust SoftwareRobust Software
Robust Software
 
Version Control - Patterns and Practices
Version Control - Patterns and PracticesVersion Control - Patterns and Practices
Version Control - Patterns and Practices
 
Requiem (For Windows XP)
Requiem (For Windows XP)Requiem (For Windows XP)
Requiem (For Windows XP)
 
(Re)Reading the Classics
(Re)Reading the Classics(Re)Reading the Classics
(Re)Reading the Classics
 
Recycle Bin 101
Recycle Bin 101Recycle Bin 101
Recycle Bin 101
 
The Art of Code
The Art of CodeThe Art of Code
The Art of Code
 

Dernier

+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
VictorSzoltysek
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
mohitmore19
 

Dernier (20)

10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 

A Test of Strength

Notes de l'éditeur

  1. I’m a freelance developer working with “enterprise grade” technology. This is a talk about both the mechanics and psychology of writing good tests.
  2. An expedited walk through my journey and where I went wrong. In some senses it’s a Rite of Passage, you may still need to go through it – I can only show you my path.
  3. Started out with simpler programs that can be (had to be) manually tested (GUIs). The test scenarios were failing small and focused on the feature so regressions were caught by QA.
  4. “Unit testing” accomplished by using Steve Maguire's (Writing Solid Code) advice about stepping through the code with a debugger. Ask yourself 2 questions – How could I have prevented this bug and how could I have automatically detected this bug? Positive effects on design as it meant you needed to be able to easily get into the debugger in the first place (i.e. test harnesses).
  5. Slip-up caused by refactoring not found by manual testing. Bug found by unrelated automated tests that started failing.
  6. I was now sold on the idea of automated unit tests, at least, for catching regressions. But I still had many reservations about the tool and technique – time required for writing tests, not paid too write tests, short term loss of productivity, etc.
  7. Premature optimisation does not just relate to software performance, you can prematurely optimise other endeavours too. In this case I thought I could optimise the process of writing tests by leaving out all the tricky boiler-plate stuff, like the name.
  8. This is a test I wrote for a C++ based command line parser. What do you think it tests? Note the test (function) name is not missing – the framework allows you to elide it by using scopes instead! I thought I was being clever and more productive by not being verbose.
  9. Yes it’s a backronym .
  10. My dad who was a bookkeeper and taught me to use different techniques to verify my answers. Naturally I didn’t listen and tried to skip over the boring stuff to get to more fun things.
  11. Term comes from the hardware world.
  12. Tests need as much TLC as production code, they are not an afterthought they are instrumental to delivery.
  13. How do you test the tests? When you’re not sure what coverage there is you can manually break the code and see how it fails.
  14. Test behaviours, not methods – how do you test a ctor? Property based testing puts the emphasis on this rather than canned examples.
  15. Replace the swathes of stale, fragmented documentation with the same intent, but in code. Introduces some overall structure instead of just being an ad-hoc set of test cases.
  16. Is it a testing “pyramid” or just some other kind of “polygon”? Monoliths and microservices may have different balances due to smaller scope.
  17. A short tale about having the courage to try and unit test a small change in a very old codebase.
  18. Probably the most important aspect of writing strong tests is being concise about the behaviour. Struggling to write the test name is a smell that I’m not sure what I’m supposed to be doing. When I write code first I’m saying to myself “I don’t know what I’m doing so I’ll just make something up” – that’s not focusing on the problem.
  19. Tests don’t have the same rules as production code, they serve a different purpose. Introduce structure to break up repetition in the scenarios.
  20. Example where I found a bug purely from the test names and assertions.
  21. XP’s five values are communication, simplicity, feedback, courage and respect. Strong tests satisfy four of those five values with the most important one being the courage to make changes.
  22. No book to peddle, but here are some links...