SlideShare ist ein Scribd-Unternehmen logo
1 von 51
1
C++ Testing: Techniques, Tips and Tricks
Clare Macrae (She/her)
clare@claremacrae.co.uk
25 February 2020
Cpp Europe
2
About Me
• C++ and Qt developer since 1999
• My mission: Sustainable and efficient testing and refactoring of legacy code
– Co-author of “Approval Tests for C++”
• Consulting & training
– https://claremacrae.co.uk
• All links from this talk via:
– github.com/claremacrae/talks
3
Why?
• Share things I wish I knew earlier
– Some well known
– Some less so…
• High-level overview, with links
– Avoiding detail
• Anything unclear?
– Please ask!
4
Assumptions
• Value of testing – safety net!
• No worries about types of tests
– (unit, integration, regression)
5
Foundations
6
Tip: Pick a Test Framework
• Lots to choose from, including:
• Get to know it well!
7
Catch2 basic example
// Let Catch provide main():
#define CATCH_CONFIG_MAIN
#include <catch2/catch.hpp>
int Factorial( int number ) {
return number <= 1 ? 1 : Factorial( number - 1 ) * number;
}
TEST_CASE( "Factorial of 0 is 1" ) {
REQUIRE( Factorial(0) == 1 );
}
TEST_CASE( "Factorials of 1 and higher are computed" ) {
REQUIRE( Factorial(1) == 1 );
REQUIRE( Factorial(2) == 2 );
REQUIRE( Factorial(3) == 6 );
REQUIRE( Factorial(10) == 3628800 );
}
8
But what about
Real World Code?
9
Rarely that simple!
• Long methods
• Interdependent code
• Tests hard to set up
• Not designed to be testable
10
Tip: Take any reasonable measure!
• … to get code tested!
• Don’t get hung up on perfect code…
• What does that mean?
11
Tip: Take any reasonable measure!
• When you are stuck, write the test you want
• Then safely do whatever you need to your implementation – temporarily!
– Make method static to call from outside?
– Add getters – and maybe even setters?
– Public data?
• Hold your nose!
• Then refactor
12
Prioritise Testable code
Over Perfect code
13
How do I test private code?
Don’t!
14
Tip: Don’t test private code
• Automated tests give freedom to safely change implementation
• Testing private code breaks that
• Only test observable – public – behaviours
15
What could possibly go wrong?
• It’s easy to think your test is passing…
• I’ve been bitten by all of these:
– Forget to add test source to build
– IDE calls a different test
– Test is doing the wrong thing
– Test is accidentally disabled
16
Never trust a test until
you have seen it fail!
17
Book recommendations
18
Summary: Foundations
• Use a test framework – get to know it well
• Take any reasonable measure to add tests
– Then improve it
• Test public behaviour – not private implementation
• Testable code over perfect code
• Never trust a test until you have seen it fail
19
Private code revisited
20
How do I test private code?
Don’t!
21
But what if…
• Tiny real world example
• “GoToLineTool” widget
• User can type in to the spinner
22
Testing goal
• Test that widget communicates changes correctly when user types in to widget
• lineNumberChanged()
• How to test that?
23
Options – none are satisfactory
• Ideas
– Search the widget hierarchy for widgets by name
– Make the spinner widget data member public
– Provide a public accessor to the data member
– Make the test a friend of the class GoToLineTool class
• All if these require the test to be reworked if widget changes
24
Goal: Make tests super easy to write
• And super easy to maintain…
• Test code accessing widgets directly makes that hard
25
Technique: Separate concerns with Fixture
class GoToLineTool : public
QWidget
{
...
public/protected/private:
QSpinBox* spinBox();
QToolButton* goButton();
Implementation Tests – lots of them!Test Fixture
class GoToLineToolFixture
{
private:
GoToLineTool mGoToLineWidget;
public:
void typeCharacterIntoSpinner(
QChar character);
...
TEST_CASE_METHOD(
GoToLineToolFixture,
"GoToLineTool …")
{
// Ask Fixture to act
// on GoToLineTool
typeCharacterIntoSpinner('1');
}
26
Summary: Fixtures
• Test Fixtures can make tests of complex code expressive
• And Maintainable
27
Inheriting Legacy/Existing Code
28
Typical Scenario
• I've inherited some
legacy code
• It's valuable
• I need to add feature
• Or fix bug
• How can I ever break
out of this loop?
Need to
change
the code
No tests
Not
designed
for testing
Needs
refactoring
to add
tests
Can’t
refactor
without
tests
29
Typical Scenario
•
•
•
•
•
Need to
change
the code
No tests
Not
designed
for testing
Needs
refactoring
to add
tests
Can’t
refactor
without
tests
Topics of
this part
30
Golden Master Test Setup
Input
Data
Existing
Code
Save
“Golden
Master”
31
Golden Master Tests In Use
Input
Data
Updated
Code
Pass
Fail
Output
same?
Yes
No
32
Approval Tests
TEST_CASE( "Factorials up to 10" )
{
// Create a container with values 0 ... 10 inclusive
std::vector<int> inputs(11);
std::iota(inputs.begin(), inputs.end(), 0);
// Act on all values in inputs container:
Approvals::verifyAll("Factorial", inputs,
[](auto i, auto& os)
{
os << i << "! => " << Factorial(i);
});
}
33
More Info: Quickly Testing Legacy C++ Code
with Approval Tests
34
Scenario: Golden Master is a log file
• Dates and times?
• Object addresses?
2019-01-29 15:27
35
Options for unstable output
• Introduce date-time abstraction?
• Customised comparison function?
• Or: strip dates from the log file
– Credit: Llewellyn Falco
36
Tip: Rewrite output file, before testing it
2019-01-29 15:27 [date-time-stamp]
37
Summary: Legacy Code
• Approval Tests
• Be creative to make your tests work for you!
• After adding tests, start refactoring for maintainability
38
Testing Qt User Interfaces
39
40
Introducing ApprovalTests.cpp.Qt
•Goals
• Quickly start testing Qt code
– Useful even if you don’t use Approval Tests!
• Approval Tests support for Qt types
– Easy saving of state in Golden Master files
• https://github.com/approvals/ApprovalTests.cpp.Qt
• https://github.com/approvals/ApprovalTests.cpp.Qt.StarterProject
• v.0.0.1
41
Example: Checking Table Contents
• Inherited complex code to set up a table
• Want to add at least a first test – of the text in the cells
42
Verifying a QTableWidget
TEST_CASE("It approves a QTableWidget")
{
// A note on naming: QTableWidget is a concrete class that implements
// the more general QTableView. Here we create a QTableWidget,
// for convenience.
QTableWidget tableWidget;
populateTable(tableWidget);
ApprovalTestsQt::verifyQTableView(tableWidget);
}
43
Approval file: .tsv
44
Summary: ApprovalTests.cpp.Qt
• More on this and on using Fixtures to write Expressive, Maintainable Tests
– slideshare.net/ClareMacrae/quickly-testing-qt-desktop-applications
45
Maintaining Tests
46
Scenario: Tests too slow for CI
• “Builds take 2 to 3 days!” => No hope of Continuous Integration
• Most of that was running tests
• No prospect of speeding up some very slow tests
47
Solution: Don’t run slow tests during day
• Mark some tests as Slow
– Filtering built in to Google Test Framework
• Teach CI system to run sub-set of tests
– Only run the Slow tests at night
– Everything else run on every commit
• Thanks to Michael Platings for making this happen!
48
Tip: Never tolerate Flickering tests
• Tests that fail randomly
• Rapidly devalue other tests
• Fix them, or delete them!
• Especially don’t mix performance tests with unit tests
49
Summary: Maintaining Tests
• Fast feedback from Continuous Integration
• Stomp on flickering tests
50
Summary
• It’s never too late to start testing!
– Pick a framework and practice it
– Explore different types of testing
• You can test legacy code too!
• Keep maintaining your tests
• Even GUIs can be tested
51
C++ Testing: Techniques, Tips and Tricks
• All links from this talk, and more, via:
– bit.ly/CppTestingTips
– github.com/claremacrae/talks
• Sustainable and efficient testing and refactoring of legacy code
• Consulting & Training
– https://claremacrae.co.uk
– clare@claremacrae.co.uk
• Any Questions?
• Any More Tips?

Weitere ähnliche Inhalte

Was ist angesagt?

Solit 2012, TDD и отдельные аспекты тестирования в Java, Антонина Шафранская
Solit 2012, TDD и отдельные аспекты тестирования в Java, Антонина ШафранскаяSolit 2012, TDD и отдельные аспекты тестирования в Java, Антонина Шафранская
Solit 2012, TDD и отдельные аспекты тестирования в Java, Антонина Шафранская
solit
 
Java Unit Test and Coverage Introduction
Java Unit Test and Coverage IntroductionJava Unit Test and Coverage Introduction
Java Unit Test and Coverage Introduction
Alex Su
 
Presentation_C++UnitTest
Presentation_C++UnitTestPresentation_C++UnitTest
Presentation_C++UnitTest
Raihan Masud
 

Was ist angesagt? (19)

ES3-2020-05 Testing
ES3-2020-05 TestingES3-2020-05 Testing
ES3-2020-05 Testing
 
Stopping the Rot - Putting Legacy C++ Under Test
Stopping the Rot - Putting Legacy C++ Under TestStopping the Rot - Putting Legacy C++ Under Test
Stopping the Rot - Putting Legacy C++ Under Test
 
Solit 2012, TDD и отдельные аспекты тестирования в Java, Антонина Шафранская
Solit 2012, TDD и отдельные аспекты тестирования в Java, Антонина ШафранскаяSolit 2012, TDD и отдельные аспекты тестирования в Java, Антонина Шафранская
Solit 2012, TDD и отдельные аспекты тестирования в Java, Антонина Шафранская
 
VT.NET 20160411: An Intro to Test Driven Development (TDD)
VT.NET 20160411: An Intro to Test Driven Development (TDD)VT.NET 20160411: An Intro to Test Driven Development (TDD)
VT.NET 20160411: An Intro to Test Driven Development (TDD)
 
Java Unit Test and Coverage Introduction
Java Unit Test and Coverage IntroductionJava Unit Test and Coverage Introduction
Java Unit Test and Coverage Introduction
 
The Test way
The Test wayThe Test way
The Test way
 
TDD and the Legacy Code Black Hole
TDD and the Legacy Code Black HoleTDD and the Legacy Code Black Hole
TDD and the Legacy Code Black Hole
 
Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven Development
 
Test driven development - JUnit basics and best practices
Test driven development - JUnit basics and best practicesTest driven development - JUnit basics and best practices
Test driven development - JUnit basics and best practices
 
Presentation_C++UnitTest
Presentation_C++UnitTestPresentation_C++UnitTest
Presentation_C++UnitTest
 
TDD in Python With Pytest
TDD in Python With PytestTDD in Python With Pytest
TDD in Python With Pytest
 
IntroTestMore
IntroTestMoreIntroTestMore
IntroTestMore
 
Working Effectively with Legacy Code
Working Effectively with Legacy CodeWorking Effectively with Legacy Code
Working Effectively with Legacy Code
 
TDD in Go with Ginkgo and Gomega
TDD in Go with Ginkgo and GomegaTDD in Go with Ginkgo and Gomega
TDD in Go with Ginkgo and Gomega
 
Testing, Learning and Professionalism — 20171214
Testing, Learning and Professionalism — 20171214Testing, Learning and Professionalism — 20171214
Testing, Learning and Professionalism — 20171214
 
MUTANTS KILLER - PIT: state of the art of mutation testing system
MUTANTS KILLER - PIT: state of the art of mutation testing system MUTANTS KILLER - PIT: state of the art of mutation testing system
MUTANTS KILLER - PIT: state of the art of mutation testing system
 
(automatic) Testing: from business to university and back
(automatic) Testing: from business to university and back(automatic) Testing: from business to university and back
(automatic) Testing: from business to university and back
 
Greach 2015 Spock workshop
Greach 2015 Spock workshopGreach 2015 Spock workshop
Greach 2015 Spock workshop
 
Test Driven Development with Sql Server
Test Driven Development with Sql ServerTest Driven Development with Sql Server
Test Driven Development with Sql Server
 

Ähnlich wie Cpp Testing Techniques Tips and Tricks - Cpp Europe

How to become a testing expert
How to become a testing expertHow to become a testing expert
How to become a testing expert
gaoliang641
 

Ähnlich wie Cpp Testing Techniques Tips and Tricks - Cpp Europe (20)

A la découverte des google/test (aka gtest)
A la découverte des google/test (aka gtest)A la découverte des google/test (aka gtest)
A la découverte des google/test (aka gtest)
 
Quickly Testing Legacy Cpp Code - ACCU Cambridge 2019
Quickly Testing Legacy Cpp Code - ACCU Cambridge 2019Quickly Testing Legacy Cpp Code - ACCU Cambridge 2019
Quickly Testing Legacy Cpp Code - ACCU Cambridge 2019
 
Kill the mutants - A better way to test your tests
Kill the mutants - A better way to test your testsKill the mutants - A better way to test your tests
Kill the mutants - A better way to test your tests
 
Kill the mutants and test your tests - Roy van Rijn
Kill the mutants and test your tests - Roy van RijnKill the mutants and test your tests - Roy van Rijn
Kill the mutants and test your tests - Roy van Rijn
 
Qt test framework
Qt test frameworkQt test framework
Qt test framework
 
QA Meetup at Signavio (Berlin, 06.06.19)
QA Meetup at Signavio (Berlin, 06.06.19)QA Meetup at Signavio (Berlin, 06.06.19)
QA Meetup at Signavio (Berlin, 06.06.19)
 
CNUG TDD June 2014
CNUG TDD June 2014CNUG TDD June 2014
CNUG TDD June 2014
 
Test automation engineer
Test automation engineerTest automation engineer
Test automation engineer
 
Test driven development
Test driven developmentTest driven development
Test driven development
 
Breaking Dependencies to Allow Unit Testing
Breaking Dependencies to Allow Unit TestingBreaking Dependencies to Allow Unit Testing
Breaking Dependencies to Allow Unit Testing
 
Getting Started with Test-Driven Development at PHPtek 2023
Getting Started with Test-Driven Development at PHPtek 2023Getting Started with Test-Driven Development at PHPtek 2023
Getting Started with Test-Driven Development at PHPtek 2023
 
How to become a testing expert
How to become a testing expertHow to become a testing expert
How to become a testing expert
 
Westrich spock-assets-gum
Westrich spock-assets-gumWestrich spock-assets-gum
Westrich spock-assets-gum
 
[Webinar] Qt Test-Driven Development Using Google Test and Google Mock
[Webinar] Qt Test-Driven Development Using Google Test and Google Mock[Webinar] Qt Test-Driven Development Using Google Test and Google Mock
[Webinar] Qt Test-Driven Development Using Google Test and Google Mock
 
Developers Testing - Girl Code at bloomon
Developers Testing - Girl Code at bloomonDevelopers Testing - Girl Code at bloomon
Developers Testing - Girl Code at bloomon
 
TDD and Related Techniques for Non Developers (2012)
TDD and Related Techniques for Non Developers (2012)TDD and Related Techniques for Non Developers (2012)
TDD and Related Techniques for Non Developers (2012)
 
Building unit tests correctly with visual studio 2013
Building unit tests correctly with visual studio 2013Building unit tests correctly with visual studio 2013
Building unit tests correctly with visual studio 2013
 
I.T.A.K.E Unconference - Mutation testing to the rescue of your tests
I.T.A.K.E Unconference - Mutation testing to the rescue of your testsI.T.A.K.E Unconference - Mutation testing to the rescue of your tests
I.T.A.K.E Unconference - Mutation testing to the rescue of your tests
 
Test it! Unit, mocking and in-container Meet Arquillian!
Test it! Unit, mocking and in-container Meet Arquillian!Test it! Unit, mocking and in-container Meet Arquillian!
Test it! Unit, mocking and in-container Meet Arquillian!
 
Quickly Testing Qt Desktop Applications
Quickly Testing Qt Desktop ApplicationsQuickly Testing Qt Desktop Applications
Quickly Testing Qt Desktop Applications
 

Mehr von Clare Macrae

Quickly and Effectively Testing Legacy c++ Code with Approval Tests mu cpp
Quickly and Effectively Testing Legacy c++ Code with Approval Tests   mu cppQuickly and Effectively Testing Legacy c++ Code with Approval Tests   mu cpp
Quickly and Effectively Testing Legacy c++ Code with Approval Tests mu cpp
Clare Macrae
 
Quickly and Effectively Testing Legacy C++ Code with Approval Tests
Quickly and Effectively Testing Legacy C++ Code with Approval TestsQuickly and Effectively Testing Legacy C++ Code with Approval Tests
Quickly and Effectively Testing Legacy C++ Code with Approval Tests
Clare Macrae
 
Quickly Testing Legacy C++ Code with Approval Tests
Quickly Testing Legacy C++ Code with Approval TestsQuickly Testing Legacy C++ Code with Approval Tests
Quickly Testing Legacy C++ Code with Approval Tests
Clare Macrae
 

Mehr von Clare Macrae (11)

Testing Superpowers: Using CLion to Add Tests Easily
Testing Superpowers: Using CLion to Add Tests EasilyTesting Superpowers: Using CLion to Add Tests Easily
Testing Superpowers: Using CLion to Add Tests Easily
 
Quickly and Effectively Testing Legacy c++ Code with Approval Tests mu cpp
Quickly and Effectively Testing Legacy c++ Code with Approval Tests   mu cppQuickly and Effectively Testing Legacy c++ Code with Approval Tests   mu cpp
Quickly and Effectively Testing Legacy c++ Code with Approval Tests mu cpp
 
Quickly and Effectively Testing Legacy C++ Code with Approval Tests
Quickly and Effectively Testing Legacy C++ Code with Approval TestsQuickly and Effectively Testing Legacy C++ Code with Approval Tests
Quickly and Effectively Testing Legacy C++ Code with Approval Tests
 
How to use Approval Tests for C++ Effectively
How to use Approval Tests for C++ EffectivelyHow to use Approval Tests for C++ Effectively
How to use Approval Tests for C++ Effectively
 
Code samples that actually compile - Clare Macrae
Code samples that actually compile - Clare MacraeCode samples that actually compile - Clare Macrae
Code samples that actually compile - Clare Macrae
 
Quickly Testing Legacy C++ Code with Approval Tests
Quickly Testing Legacy C++ Code with Approval TestsQuickly Testing Legacy C++ Code with Approval Tests
Quickly Testing Legacy C++ Code with Approval Tests
 
Quickly testing legacy code cppp.fr 2019 - clare macrae
Quickly testing legacy code   cppp.fr 2019 - clare macraeQuickly testing legacy code   cppp.fr 2019 - clare macrae
Quickly testing legacy code cppp.fr 2019 - clare macrae
 
Quickly Testing Legacy Code - ACCU York April 2019
Quickly Testing Legacy Code - ACCU York April 2019Quickly Testing Legacy Code - ACCU York April 2019
Quickly Testing Legacy Code - ACCU York April 2019
 
Quickly testing legacy code
Quickly testing legacy codeQuickly testing legacy code
Quickly testing legacy code
 
Escaping 5 decades of monolithic annual releases
Escaping 5 decades of monolithic annual releasesEscaping 5 decades of monolithic annual releases
Escaping 5 decades of monolithic annual releases
 
CCDC’s (ongoing) Journey to Continuous Delivery - London Continuous Delivery ...
CCDC’s (ongoing) Journey to Continuous Delivery - London Continuous Delivery ...CCDC’s (ongoing) Journey to Continuous Delivery - London Continuous Delivery ...
CCDC’s (ongoing) Journey to Continuous Delivery - London Continuous Delivery ...
 

Kürzlich hochgeladen

TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
mohitmore19
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
VishalKumarJha10
 
+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
 

Kürzlich hochgeladen (20)

%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
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
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
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
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
ManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide Deck
 
Pharm-D Biostatistics and Research methodology
Pharm-D Biostatistics and Research methodologyPharm-D Biostatistics and Research methodology
Pharm-D Biostatistics and Research methodology
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
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
 
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verifiedSector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
Sector 18, Noida Call girls :8448380779 Model Escorts | 100% verified
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
 
+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...
 

Cpp Testing Techniques Tips and Tricks - Cpp Europe

  • 1. 1 C++ Testing: Techniques, Tips and Tricks Clare Macrae (She/her) clare@claremacrae.co.uk 25 February 2020 Cpp Europe
  • 2. 2 About Me • C++ and Qt developer since 1999 • My mission: Sustainable and efficient testing and refactoring of legacy code – Co-author of “Approval Tests for C++” • Consulting & training – https://claremacrae.co.uk • All links from this talk via: – github.com/claremacrae/talks
  • 3. 3 Why? • Share things I wish I knew earlier – Some well known – Some less so… • High-level overview, with links – Avoiding detail • Anything unclear? – Please ask!
  • 4. 4 Assumptions • Value of testing – safety net! • No worries about types of tests – (unit, integration, regression)
  • 6. 6 Tip: Pick a Test Framework • Lots to choose from, including: • Get to know it well!
  • 7. 7 Catch2 basic example // Let Catch provide main(): #define CATCH_CONFIG_MAIN #include <catch2/catch.hpp> int Factorial( int number ) { return number <= 1 ? 1 : Factorial( number - 1 ) * number; } TEST_CASE( "Factorial of 0 is 1" ) { REQUIRE( Factorial(0) == 1 ); } TEST_CASE( "Factorials of 1 and higher are computed" ) { REQUIRE( Factorial(1) == 1 ); REQUIRE( Factorial(2) == 2 ); REQUIRE( Factorial(3) == 6 ); REQUIRE( Factorial(10) == 3628800 ); }
  • 8. 8 But what about Real World Code?
  • 9. 9 Rarely that simple! • Long methods • Interdependent code • Tests hard to set up • Not designed to be testable
  • 10. 10 Tip: Take any reasonable measure! • … to get code tested! • Don’t get hung up on perfect code… • What does that mean?
  • 11. 11 Tip: Take any reasonable measure! • When you are stuck, write the test you want • Then safely do whatever you need to your implementation – temporarily! – Make method static to call from outside? – Add getters – and maybe even setters? – Public data? • Hold your nose! • Then refactor
  • 13. 13 How do I test private code? Don’t!
  • 14. 14 Tip: Don’t test private code • Automated tests give freedom to safely change implementation • Testing private code breaks that • Only test observable – public – behaviours
  • 15. 15 What could possibly go wrong? • It’s easy to think your test is passing… • I’ve been bitten by all of these: – Forget to add test source to build – IDE calls a different test – Test is doing the wrong thing – Test is accidentally disabled
  • 16. 16 Never trust a test until you have seen it fail!
  • 18. 18 Summary: Foundations • Use a test framework – get to know it well • Take any reasonable measure to add tests – Then improve it • Test public behaviour – not private implementation • Testable code over perfect code • Never trust a test until you have seen it fail
  • 20. 20 How do I test private code? Don’t!
  • 21. 21 But what if… • Tiny real world example • “GoToLineTool” widget • User can type in to the spinner
  • 22. 22 Testing goal • Test that widget communicates changes correctly when user types in to widget • lineNumberChanged() • How to test that?
  • 23. 23 Options – none are satisfactory • Ideas – Search the widget hierarchy for widgets by name – Make the spinner widget data member public – Provide a public accessor to the data member – Make the test a friend of the class GoToLineTool class • All if these require the test to be reworked if widget changes
  • 24. 24 Goal: Make tests super easy to write • And super easy to maintain… • Test code accessing widgets directly makes that hard
  • 25. 25 Technique: Separate concerns with Fixture class GoToLineTool : public QWidget { ... public/protected/private: QSpinBox* spinBox(); QToolButton* goButton(); Implementation Tests – lots of them!Test Fixture class GoToLineToolFixture { private: GoToLineTool mGoToLineWidget; public: void typeCharacterIntoSpinner( QChar character); ... TEST_CASE_METHOD( GoToLineToolFixture, "GoToLineTool …") { // Ask Fixture to act // on GoToLineTool typeCharacterIntoSpinner('1'); }
  • 26. 26 Summary: Fixtures • Test Fixtures can make tests of complex code expressive • And Maintainable
  • 28. 28 Typical Scenario • I've inherited some legacy code • It's valuable • I need to add feature • Or fix bug • How can I ever break out of this loop? Need to change the code No tests Not designed for testing Needs refactoring to add tests Can’t refactor without tests
  • 29. 29 Typical Scenario • • • • • Need to change the code No tests Not designed for testing Needs refactoring to add tests Can’t refactor without tests Topics of this part
  • 30. 30 Golden Master Test Setup Input Data Existing Code Save “Golden Master”
  • 31. 31 Golden Master Tests In Use Input Data Updated Code Pass Fail Output same? Yes No
  • 32. 32 Approval Tests TEST_CASE( "Factorials up to 10" ) { // Create a container with values 0 ... 10 inclusive std::vector<int> inputs(11); std::iota(inputs.begin(), inputs.end(), 0); // Act on all values in inputs container: Approvals::verifyAll("Factorial", inputs, [](auto i, auto& os) { os << i << "! => " << Factorial(i); }); }
  • 33. 33 More Info: Quickly Testing Legacy C++ Code with Approval Tests
  • 34. 34 Scenario: Golden Master is a log file • Dates and times? • Object addresses? 2019-01-29 15:27
  • 35. 35 Options for unstable output • Introduce date-time abstraction? • Customised comparison function? • Or: strip dates from the log file – Credit: Llewellyn Falco
  • 36. 36 Tip: Rewrite output file, before testing it 2019-01-29 15:27 [date-time-stamp]
  • 37. 37 Summary: Legacy Code • Approval Tests • Be creative to make your tests work for you! • After adding tests, start refactoring for maintainability
  • 38. 38 Testing Qt User Interfaces
  • 39. 39
  • 40. 40 Introducing ApprovalTests.cpp.Qt •Goals • Quickly start testing Qt code – Useful even if you don’t use Approval Tests! • Approval Tests support for Qt types – Easy saving of state in Golden Master files • https://github.com/approvals/ApprovalTests.cpp.Qt • https://github.com/approvals/ApprovalTests.cpp.Qt.StarterProject • v.0.0.1
  • 41. 41 Example: Checking Table Contents • Inherited complex code to set up a table • Want to add at least a first test – of the text in the cells
  • 42. 42 Verifying a QTableWidget TEST_CASE("It approves a QTableWidget") { // A note on naming: QTableWidget is a concrete class that implements // the more general QTableView. Here we create a QTableWidget, // for convenience. QTableWidget tableWidget; populateTable(tableWidget); ApprovalTestsQt::verifyQTableView(tableWidget); }
  • 44. 44 Summary: ApprovalTests.cpp.Qt • More on this and on using Fixtures to write Expressive, Maintainable Tests – slideshare.net/ClareMacrae/quickly-testing-qt-desktop-applications
  • 46. 46 Scenario: Tests too slow for CI • “Builds take 2 to 3 days!” => No hope of Continuous Integration • Most of that was running tests • No prospect of speeding up some very slow tests
  • 47. 47 Solution: Don’t run slow tests during day • Mark some tests as Slow – Filtering built in to Google Test Framework • Teach CI system to run sub-set of tests – Only run the Slow tests at night – Everything else run on every commit • Thanks to Michael Platings for making this happen!
  • 48. 48 Tip: Never tolerate Flickering tests • Tests that fail randomly • Rapidly devalue other tests • Fix them, or delete them! • Especially don’t mix performance tests with unit tests
  • 49. 49 Summary: Maintaining Tests • Fast feedback from Continuous Integration • Stomp on flickering tests
  • 50. 50 Summary • It’s never too late to start testing! – Pick a framework and practice it – Explore different types of testing • You can test legacy code too! • Keep maintaining your tests • Even GUIs can be tested
  • 51. 51 C++ Testing: Techniques, Tips and Tricks • All links from this talk, and more, via: – bit.ly/CppTestingTips – github.com/claremacrae/talks • Sustainable and efficient testing and refactoring of legacy code • Consulting & Training – https://claremacrae.co.uk – clare@claremacrae.co.uk • Any Questions? • Any More Tips?

Hinweis der Redaktion

  1. Harder than testing non-Graphical User Interface code But it’s still a learnable skill
  2. Harder than testing non-Graphical User Interface code But it’s still a learnable skill
  3. Harder than testing non-Graphical User Interface code But it’s still a learnable skill
  4. Harder than testing non-Graphical User Interface code But it’s still a learnable skill
  5. Harder than testing non-Graphical User Interface code But it’s still a learnable skill
  6. Note the dependency order
  7. Another phrase for the Golden Master output is “Known Good” output.
  8. A lot of this stuff you can get going on your own. If you get stuck, I can help you!