SlideShare ist ein Scribd-Unternehmen logo
1 von 28
Downloaden Sie, um offline zu lesen
Topics
                                    TDD for Embedded C
                    Talk to us on Twitter
                http://twitter.com/jwgrenning
                                                                                                                                                                                       •    The why and what of TDD
                http://twitter.com/basvodde                                                                                                                                            •    Embedded adaptation
               Find us on linkedin.com                                                                                                                                                 •    Abstracting HW and OS
       http://www.linkedin.com/in/jwgrenning
       http://www.linkedin.com/in/basvodde                                                                                                                                             •    Mocking the silicon
               Remind us how we met.
                                                                                                                                                                                       •    Test-double substitution options
         http://www.renaissancesoftware.net
           http:// www.jamesgrenning.com                                   Scaling Lean & Agile
                                                                                                                               Practices for
                                                                                                                           Scaling Lean & Agile
                                                                                                                                                                                       •    Function pointer substitution
                                                                              Development                                     Development
                 http://www.odd-e.com                                        Thinking and Organizational Tools
                                                                                   for Large-Scale Scrum

                                                                                      Craig Larman
                                                                                       Bas Vodde
                                                                                                                            Large, Multisite, and Offshore Products
                                                                                                                                   with Large-Scale Scrum

                                                                                                                                        Craig Larman
                                                                                                                                         Bas Vodde
                                                                                                                                                                                       •    Preprocessor substitution
                                                                                                                                                                                       •    TDD next to an RTOS
       Come to a full version of James’ TDD
                for Embedded C
          October 2012. Phoenix, AZ

                                                                                                                   www.renaissancesoftware.net                                                                                                                          www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                                                          james@renaissancesoftware.net                        1   Copyright © 2008-2012 James W. Grenning                                                     james@renaissancesoftware.net   2
All Rights Reserved. For use by training attendees.     Agile 2012, Grapevine, TX                                       basv@odd-e.com                                    All Rights Reserved. For use by training attendees.   Agile 2012, Grapevine, TX                    basv@odd-e.com




                                                                                                                                                                                             This Work Flow is Designed to Allow
                                                                                                                                                                                                          Defects


                                                       Why TDD?
                                                      What is TDD?                                                                                                                                     Development

                                                                                                                                                                                                                                                             Test




                                                                                                                                                                                                                                                            Defects
                                                                                                                   www.renaissancesoftware.net                                                                                                                          www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                                                          james@renaissancesoftware.net                        3   Copyright © 2008-2012 James W. Grenning                                                     james@renaissancesoftware.net   4
All Rights Reserved. For use by training attendees.     Agile 2012, Grapevine, TX                                       basv@odd-e.com                                    All Rights Reserved. For use by training attendees.   Agile 2012, Grapevine, TX                    basv@odd-e.com
The Physics of Debug Later
                                                         Your program will have                                                                                                Programming (DLP)
                                                         bugs. And they will
                                                         surprise you when you                                                                                                                Td                                Tfind         T fix

                                                         find them.
                                                                                                                                                                                                                                                        Time


                                                                                                                                                             Mistake made                          Bug discovery
                                                                                                                                                             (bug injection)
                                                                                                                                                                                                                               Bug found   Bug fixed


                                                                                                                                                     • As Td increases, Tfind increases dramatically
                                                                                                                                                     • Tfix is usually short, but can increase with Td


                                                                                                      www.renaissancesoftware.net                                                                                                            www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                                             james@renaissancesoftware.net   5   Copyright © 2008-2012 James W. Grenning                                                            james@renaissancesoftware.net   6
All Rights Reserved. For use by training attendees.   Agile 2012, Grapevine, TX                            basv@odd-e.com               All Rights Reserved. For use by training attendees.        Agile 2012, Grapevine, TX                      basv@odd-e.com




         A Bug’s Life                                                                                                                                                                         Edsger Dijkstra
                                                                                                                                                 Those who want really reliable
                                                                                                                                                 software will discover that they
                                                                                                                                                 must find means of avoiding the
                                                                                                                                                 majority of bugs to start with, and
                                                                                                                                                 as a result, the programming
                                                                                                                                                 process will become cheaper. If you
                                                                                                                                                 want more effective programmers,
                                                                                                                                                 you will discover that they should
                                                                                                                                                 not waste their time debugging,
                                                                                                                                                 they should not introduce the bugs
                                                                                                                                                 to start with.
                                                                 From http://www.softwaretestinghelp.com/bug-life-cycle/
                                                                                                      www.renaissancesoftware.net                                                                                                            www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                                             james@renaissancesoftware.net   7   Copyright © 2008-2012 James W. Grenning                                                            james@renaissancesoftware.net   8
All Rights Reserved. For use by training attendees.   Agile 2012, Grapevine, TX                            basv@odd-e.com               All Rights Reserved. For use by training attendees.                                                       basv@odd-e.com
Can we Realize                                                                                    Being g
                                 Dijkstra’s Dream and                                                                                          ood at c
                                                                                                                                      is not T          hasing
                                  Prevent Defects with                                                                                         echnica           bugs
                                                                                                                                                        l Excelle
                               Test Driven Development?                                                                                                           nce


                                                                                    www.renaissancesoftware.net                                                                                            www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                           james@renaissancesoftware.net   9    Copyright © 2008-2012 James W. Grenning                                           james@renaissancesoftware.net   10
All Rights Reserved. For use by training attendees.                                      basv@odd-e.com                All Rights Reserved. For use by training attendees.                                      basv@odd-e.com




                   Development and Test Work Together
                          Preventing Defects                                                                                                                                    A Complex system that
                                                                                                                                                                                works is invariably
                                                                                                                                                                                found to have evolved
                                                                                                                                                                                from a simple system
        Development                                                                                                                                                             that worked.


                             Test




                                                                                    www.renaissancesoftware.net                                                                                            www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                           james@renaissancesoftware.net   11   Copyright © 2008-2012 James W. Grenning                                           james@renaissancesoftware.net   12
All Rights Reserved. For use by training attendees.   Agile 2012, Grapevine, TX          basv@odd-e.com                All Rights Reserved. For use by training attendees.   Agile 2012, Grapevine, TX          basv@odd-e.com
The Physics of Test Driven
                                                                                                                                                                          Why is it difficult to sustain?
                                            Development
                                                              T d Tfind T fix


                                                                                                         Time


                                                        Mistake
                                                                              Mistake fixed
                                                         made
                                                              Mistake  Root cause
                                                             discovery   found


             • When Td approaches zero, Tfind approaches zero                                                                                TDD:                                                       Traditional:
             • In many cases, bugs are not around long enough to be considered                                                               • Steady pace                                              • Spurts
               bugs.                                                                                                                         • Speed limits                                             • Fast when no problems!
             • See: http://www.renaissancesoftware.net/blog/archives/16                                                                      • No traffic lights (bugs)                                 • Debugging
                                                                                                                                             • Might feel slow!!                                        • Feels fast! But often slow
                                                                                                    www.renaissancesoftware.net                                                                                             www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                                           james@renaissancesoftware.net   13   Copyright © 2008-2012 James W. Grenning                                            james@renaissancesoftware.net   14
All Rights Reserved. For use by training attendees.            Agile 2012, Grapevine, TX                 basv@odd-e.com                All Rights Reserved. For use by training attendees.   Agile 2012, Grapevine, TX           basv@odd-e.com




                                                         Sustainability                              Time developers do
                                                                                                     not notice nor plan for



 Traditional                                          Speculate       Code                 Test    Debug
 development
                                                                                                                                                                                Demo and Exercise
Time                                                          vs
                                                                                                         Feels
                                                                                                         slower

 Test-driven
                                                      Spec
 development                                          ulate
                                                                           Test and Code              Debug



                                                                                                    www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                                           james@renaissancesoftware.net   15   Copyright © 2008-2012 James W. Grenning                                              www.renaissancesoftware.net   16
All Rights Reserved. For use by training attendees.            Agile 2012, Grapevine, TX                 basv@odd-e.com                All Rights Reserved. For use by training attendees.   Agile 2012, Grapevine, TX    james@renaissancesoftware.net
Cheat sheet
                                                                                                                                     /* in CheatSheetTest.cpp */
                                                                                                                                     #include "CppUTest/TestHarness.h"

                                                                                                                                     /* Declare TestGroup with name CheatSheet */
                                                                                                                                     TEST_GROUP(CheatSheet)
                                                                                                                                     {
                                                                                                                                     /* declare a setup method for the test group. Optional. */
                                                                                                                                     	   void setup ()


                                    CppUTest Quick Intro
                                                                                                                                     	   {
                                                                                                                                     /* Set method real_one to stub. Automatically restore in teardown */
                                                                                                                                     	   	    UT_PTR_SET(real_one, stub);
                                                                                                                                     	   }

                                                                                                                                     /* Declare a teardown method for the test group. Optional */
                                                                                                                                     	   void teardown()
                                                                                                                                     	   {
                                                                                                                                     	   }
                                                                                                                                     }; /* Do not forget semicolumn */                            /* In allTest.cpp */
                                                                                                                                                                                                  IMPORT_TEST_GROUP(CheatSheet);
                                                                                                                                     /* Declare one test within the test group */
                                                                                                                                     TEST(CheatSheet, TestName)                                             /* In main.cpp */
                                                                                                                                     {
                                                                                                                                     	   /* Check two longs are equal */                                    #include "CppUTest/CommandLineTestRunner.h"
                                                                                                                                     	   LONGS_EQUAL(1, 1);                                                 #include "AllTests.h"


                                                                                                                                     	     /* Check a condition */                                          int main(int ac, char** av)
                                                                                                                                     	     CHECK(true);                                                     {
                                                                                                                                                                                                              return CommandLineTestRunner::RunAllTests(ac, av);
                                                                                                                                     	     /* Check a string */                                             }
                                                                                                                                     	     STRCMP_EQUAL("HelloWorld", "HelloWorld");
                                                                                                                                     }
                                                                                            www.renaissancesoftware.net                                                                                                                www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                                   james@renaissancesoftware.net        17   Copyright © 2008-2012 James W. Grenning                                                          james@renaissancesoftware.net   18
All Rights Reserved. For use by training attendees.        Agile 2012, Grapevine, TX             basv@odd-e.com                     All Rights Reserved. For use by training attendees.     Agile 2012, Grapevine, TX                       basv@odd-e.com




                                                        Test Fixture                                                                                                                      Output Format
   Data needed
   in each test.                                TEST_GROUP(TemplateEngineTest)
                                                                                               Run before
                                                {                                               each test                                     No news is good news
                                                	 Template aTemplate;
                                                	 TemplatePlaceholderValues replacementValues;
                                                                                                                                                      ./TestFirst
                                                	 EmailFormatter *emailFormat;
                                                                                                                                                      .
                                                	 void setup() {
                                                                                                                                                      OK (1 tests, 1 ran, 1 checks, 0 ignored, 0 filtered out, 0 ms)
                                                	 	 emailFormatter = createMockFormatter();
                                                	 	 aTemplate.setEmailFormat(emailFormat);

   The data and
                                                	 }
                                                	 void teardown(){
                                                                                                                                             Give precise information when fails
                                                	 	 destroyFormatter(emailFormatter);                                                                 ./TestFirst
 setup / teardown                               	 }
      is also                                   };                                               Run after                                            TestFirst.cpp:10: error: Failure in TEST(FirstTest, First)
                                                                                                                                                      make: *** [all] Error 1
    sometimes                                   TEST(TemplateEngineTest,
                                                templatesWithoutPlaceHoldersDoNotChange)
                                                                                                 each test                                            	 expected <1 0x1>

      called:                                   {
                                                                                                                                                      	 but was <0 0x0>


   test fixture                                  	 aTemplate.set("Nothing here");
                                                   STRCMP_EQUAL("Nothing here",
                                                                                                                                                      .
                                                                                                                                                      Errors (1 failures, 1 tests, 1 ran, 1 checks, 0 ignored, 0 filtered out, 0 ms)
                                                          aTemplate.replaceValues(replacementValues).c_str());
                                                }
                                                                                            www.renaissancesoftware.net                                                                                                                www.renaissancesoftware.net
                                                                                                                          49
Copyright © 2008-2012 James W. Grenning                                                   james@renaissancesoftware.net        19   Copyright © 2008-2012 James W. Grenning                                                          james@renaissancesoftware.net   20
All Rights Reserved. For use by training attendees.        Agile 2012, Grapevine, TX             basv@odd-e.com                     All Rights Reserved. For use by training attendees.     Agile 2012, Grapevine, TX                       basv@odd-e.com
More info

             • CppUTest Github Project page:
                   – http://cpputest.github.com/cpputest/                                                                                        Adaptation for Embedded
             • The CppUTest Github repository:                                                                                                           Software
                   – https://github.com/cpputest/cpputest

             • The CppUTest Man page:
                   – http://www.cpputest.org/



                                                                                    www.renaissancesoftware.net                                                                                            www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                           james@renaissancesoftware.net   21   Copyright © 2008-2012 James W. Grenning                                           james@renaissancesoftware.net   22
All Rights Reserved. For use by training attendees.   Agile 2012, Grapevine, TX          basv@odd-e.com                All Rights Reserved. For use by training attendees.   Agile 2012, Grapevine, TX          basv@odd-e.com




                  What are the special                                                                                                              What is special about embedded
               challenges you have over a
                                                                                                                                    •    Concurrent HW development
                non-embedded developer?                                                                                             •    HW bottleneck
                                                                                                                                    •    Cross compilation
                                                                                                                                    •    Limited memory and IO
                                                                                                                                    •    Target debug
                                                                                                                                    •    Architecture




                                                                                                                                                                                                           www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                             www.renaissancesoftware.net   23   Copyright © 2008-2012 James W. Grenning                                           james@renaissancesoftware.net   24
All Rights Reserved. For use by training attendees.                               james@renaissancesoftware.net        All Rights Reserved. For use by training attendees.   Agile 2012, Grapevine, TX          basv@odd-e.com
Hardware is
                  Scarce!
             • It does not exist.
             • It is being used by
               someone else.
             • It has bugs of its
               own.




                                                                                    www.renaissancesoftware.net                                                                                            www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                           james@renaissancesoftware.net   25   Copyright © 2008-2012 James W. Grenning                                           james@renaissancesoftware.net   26
All Rights Reserved. For use by training attendees.   Agile 2012, Grapevine, TX          basv@odd-e.com                All Rights Reserved. For use by training attendees.   Agile 2012, Grapevine, TX          basv@odd-e.com




                                                                                    www.renaissancesoftware.net                                                                                            www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                           james@renaissancesoftware.net   27   Copyright © 2008-2012 James W. Grenning                                           james@renaissancesoftware.net   28
All Rights Reserved. For use by training attendees.   Agile 2012, Grapevine, TX          basv@odd-e.com                All Rights Reserved. For use by training attendees.                                      basv@odd-e.com
Minimize                      DoH!


                                                                                                                                                                                                               Debug
                                                                                                                                                                                                               on
                                                                                                                                               Copyright Fox Broadcasting. Used under fair use.
                                                                                                                                                                                                               Hardware
                                                                                        www.renaissancesoftware.net                                                                                                 www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                               james@renaissancesoftware.net   29   Copyright © 2008-2012 James W. Grenning                                                james@renaissancesoftware.net   30
All Rights Reserved. For use by training attendees.                                          basv@odd-e.com                All Rights Reserved. For use by training attendees.     Agile 2012, Grapevine, TX             basv@odd-e.com




                     Why Use Your Development System                                                                                                      How to Use Your Development
                              for a Test Bed?                                                                                                                System for a Test Bed?
            •    Waiting for hardware.                                                                                                  •    Multi-targeted code.
            •    Waiting for restart.                                                                                                   •    Must make code portable
            •    Waiting for downloads.                                                                                                 •    Must beware of hardware and OS dependencies.
            •    Waiting for long compiles.                                                                                             •    Object Oriented approach to Dependency
            •    Debugging on the target.                                                                                                    Management.
            •    Target has bugs.
            •    (Re)Configuring the lab

                                                      Avoid wasteful practices
                                                                                        www.renaissancesoftware.net                                                                                                 www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                               james@renaissancesoftware.net   31   Copyright © 2008-2012 James W. Grenning                                                james@renaissancesoftware.net   32
All Rights Reserved. For use by training attendees.       Agile 2012, Grapevine, TX          basv@odd-e.com                All Rights Reserved. For use by training attendees.     Agile 2012, Grapevine, TX             basv@odd-e.com
But There are Risks with                                                                                                  TDD Adaptation for Embedded
                                      Development System Tests                                                                                                         Development
             • Architecture differences
                                                                                                                                                 Stage 1                             Stage 2              Stage 3                    Stage 4                       Stage 5
                   – Word size
                   – Big-endian Little-endian
                   – Alignment                                                                                                                Write a Test                        Compile               Run Tests                  Run Tests                    Acceptance
                                                                                                                                              Make it Pass                       for Target             in the Eval                in Target                       Tests
             • Compiler differences                                                                                                            Refactor                          Processor              Hardware                   Hardware
             • Library differences
             • Execution differences
                                                                                                                                       More Frequent                                                                                                         Less Frequent




                                                                                                www.renaissancesoftware.net                                                                                                                        www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                                       james@renaissancesoftware.net   33   Copyright © 2008-2012 James W. Grenning                                                                       james@renaissancesoftware.net            34
All Rights Reserved. For use by training attendees.         Agile 2012, Grapevine, TX                basv@odd-e.com                All Rights Reserved. For use by training attendees.          Agile 2012, Grapevine, TX                               basv@odd-e.com




                              TDD Adaptation for Embedded                                                                                                   Continuous Integration - Embedded
                                    Development                                                                                                                                                                             3. CIS notices changes, refreshes
                                                                                                                                                                                                                            its local copy, builds and runs host


                                                                                                                                         2. Developer
              Stage 1                             Stage 2             Stage 3           Stage 4              Stage 5                     checks in work
                                                                                                                                                                                  Source Code      Continuous Integration       Test Management
                                                                                                                                         regularly.
                                                                                                                                                                                   Repository             Server                     System
                                                                                                                                                                                                                                                                     4. After
                                                                                                                                                                                                                                                                     successful host
                                                                                                                                                                                                                                                                     build/test, CIS
           Write a Test                        Compile              Run Tests           Run Tests        Acceptance                                                                                                                                                  builds and hands
           Make it Pass                       for Target            in the Eval         in Target           Tests                                                                                                                                                    images to TMS to
                                                                                                                                                                                                                                                                     deploy to
            Refactor                          Processor             Hardware            Hardware                                                                                                                                                                     simulator, eval/
                                                                                                                                                                                                                                                                     reference boards
                                                                                                                                         1. Developer has                                                                                                            or target system.
                                                                                                                                         all unit tests




                                                                                                                                                                                                                     Eval/Reference
    More Frequent                                                                                       Less Frequent                                                                                                   System
                                                                                                                                                                              Developer                                                 Simulator
                                                                                                                                                                                                      Target System
                                                                                                                                                                              Workstation
           See : http://renaissancesoftware.net/files/articles/ProgressBeforeHardware.pdf
                                                                                                                                                                                                                                               The SCR, CIS and TMS are not necessarily
                                                                                                                                                                                                                                               separate hardware systems.
                                                                                                www.renaissancesoftware.net                                                                                                                        www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                                       james@renaissancesoftware.net   35   Copyright © 2008-2012 James W. Grenning
                                                                                                                                       35                                                                                                        james@renaissancesoftware.net
All Rights Reserved. For use by training attendees.         Agile 2012, Grapevine, TX                basv@odd-e.com                All Rights Reserved. For use by training attendees.          Agile 2012, Grapevine, TX                               basv@odd-e.com
Problems Found at Appropriate Stage
               Stage                                  Problems Likely to Find in Stage

                    1           Logic, design, modularity, interface, boundary conditions

                    2           Compiler compatibility (language features)
                                Library compatibility (header files, declarations)
                                                                                                                                                             Hardware and OS Abstraction
                    3           Processor executions problems (compiler and library bugs)
                                Portability problems (word size, alignment, endian)

                    4           Ditto stage 3
                                Hardware integration problems
                                Misunderstood hardware specifications

                    5           Ditto stage 4
                                Misunderstood feature specification


                                                                                                        www.renaissancesoftware.net                                                                                                              www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                                               james@renaissancesoftware.net     37   Copyright © 2008-2012 James W. Grenning                                                           james@renaissancesoftware.net    38
All Rights Reserved. For use by training attendees.      Agile 2012, Grapevine, TX                           basv@odd-e.com                  All Rights Reserved. For use by training attendees.   Agile 2012, Grapevine, TX                          basv@odd-e.com




                                 Separation of Responsibilities                                                                                                                          Light Scheduler Design
             • Every minute, the
               RTOS wakes up
                                                                  Admin
                                                                  Console
                                                                                                 Light
                                                                                                Scheduler
                                                                                                                                                   • Program to                                          Admin
                                                                                                                                                                                                         Console
                                                                                                                                                                                                                                          Light
                                                                                                                                                                                                                                         Scheduler

               the Light                                                                +ScheduleTurnOn()                                            Interfaces                                                                 + ScheduleTurnOn()
                                                                                        +RemoveSchedule()                                                                                                                       + RemoveSchedule()
               Scheduler.                                                               +WakeUp()                  <<anonymous callback>>          • Separate interface                                                         +WakeUp()                    <<anonymous callback>>



             • If it is time for                                                                                                                     and implementation
                                                                                                                                                     as separate entities.
                                                                                                                                                                                                                        <<interface>>                <<interface>>
                                                                             Light Controller               Time Service
               one of the lights to                                         + On(id)                 + GetTime()
                                                                                                                                                                                                                     Light Controller
                                                                                                                                                                                                                    + On(id)
                                                                                                                                                                                                                                                  Time Service
                                                                                                                                                                                                                                              + GetTime()
               be controlled, the                                           + Off(id)                + SetPeriodicAlarm()                          • This design has                                                + Off(id)                 + SetPeriodicAlarm()


               LightController is                                                                                                                    good separation of                                                <<implements>>                <<implements>>


               told to turn on/off
                                                                                Hardware                      RTOS
                                                                                                                                                     responsibilities                                                    Model 42                      RTOS
                                                                                                                                                                                                                      Light Controller               Time Service
               the light.
                                                                                                                                                                                                                    Model 42 Hardware                   RTOS



                                                                                                        www.renaissancesoftware.net                                                                                                              www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                                               james@renaissancesoftware.net     39   Copyright © 2008-2012 James W. Grenning                                                           james@renaissancesoftware.net   40
All Rights Reserved. For use by training attendees.      Agile 2012, Grapevine, TX                           basv@odd-e.com                  All Rights Reserved. For use by training attendees.   Agile 2012, Grapevine, TX                          basv@odd-e.com
LightScheduler Test Fixture Design                                                                                                                                       Testing the Scheduler
                                                                     Light                                                                                  TEST(LightScheduler, light_not_changed_at_the_wrong_time)
             • Use the real                                         Scheduler
                                                                                                      Light
                                                                                                     Scheduler                                              {
                                                                      Test
               collaborators if                                                              + ScheduleTurnOn()
                                                                                                                                                                LightScheduler_ScheduleTurnOn(3, EVERYDAY, 1200);
                                                                                                                                                                FakeTimeService_SetMinute(1199);
                                                                                             + RemoveSchedule()
               you can.                                                                      +wakeUp()                                                          LightScheduler_Wakeup();
                                                                                                                                                                LONGS_EQUAL(NO_LIGHT_ID, LightControllerSpy_GetLastId());
             • Use fakes when                                                                                                                                   LONGS_EQUAL(LIGHT_STATE_UNKNOWN, LightControllerSpy_GetLastState());
                                                                                                                                                            }
               you must.                                                             <<interface>>
                                                                                  Light Controller
                                                                                                                  <<interface>>
                                                                                                                 Time Service
                                                                                + On(id)                   + GetTime()                                      TEST(LightScheduler, light_changed_at_the_right_time)
                                                                                + Off(id)                  + SetPeriodicAlarm()                             {
                                                                                                                                                                LightScheduler_ScheduleTurnOn(3, EVERYDAY, 1200);
                                                                                                                                                                FakeTimeService_SetMinute(1200);
                                                                                    <<implements>>               <<implements>>                                 LightScheduler_Wakeup();
                                                                                  Light Controller                  Fake                                        LONGS_EQUAL(3, LightControllerSpy_GetLastId());
                                                                                       Spy                       Time Service                                   LONGS_EQUAL(LIGHT_ON, LightControllerSpy_GetLastState());
                                                                                                                                                            }



                                                                                                             www.renaissancesoftware.net                                                                                            www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                                                    james@renaissancesoftware.net   41   Copyright © 2008-2012 James W. Grenning                                           james@renaissancesoftware.net   42
All Rights Reserved. For use by training attendees.            Agile 2012, Grapevine, TX                          basv@odd-e.com                All Rights Reserved. For use by training attendees.   Agile 2012, Grapevine, TX          basv@odd-e.com




                                          Light Scheduler Test List
                                                                                                                                                                                                         A Complex system that
                                             Light Scheduler Tests                                                                                                                                       works is invariably
                                             Lights are not changed at initialization
                                                                                                                                                                                                         found to have evolved
                                             Time is wrong, day is wrong, no lights are changed
                                             Day is right, time is wrong, no lights are changed                                                                                                          from a simple system
                                             Day is wrong, time is right, no lights are changed
                                             Day is right, time is right, the right light is turned on
                                             Day is right, time is right, the right light is turned off
                                                                                                                                                                                                         that worked.
                                             Schedule every day
                                             Schedule a specific day
                                             Schedule all weekdays
                                             Schedule weekend days
                                             Remove scheduled event
                                             Remove non-existent event
                                             Multiple scheduled events at the same time
                                             Multiple scheduled events for the same light
                                             Remove non scheduled light schedule
                                             Schedule the maximum supported number of events (128)
                                             Schedule too many events



                                                                                                             www.renaissancesoftware.net                                                                                            www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                                                    james@renaissancesoftware.net   43   Copyright © 2008-2012 James W. Grenning                                           james@renaissancesoftware.net   44
All Rights Reserved. For use by training attendees.            Agile 2012, Grapevine, TX                          basv@odd-e.com                All Rights Reserved. For use by training attendees.   Agile 2012, Grapevine, TX          basv@odd-e.com
Partial Skeleton Let’s Your Try the                                                                                                                 Copy/Paste THINK
                            Design and Test Ideas Early
                                                                                                                                   TEST(LightScheduler, light_not_changed_at_the_wrong_time)
                                                                                                                                   {
                                                                                                                                       LightScheduler_ScheduleTurnOn(3, EVERYDAY, 1200);
                                                                                                                                       TransitionClockTo(SUNDAY, 1199);
                                                                                                                                   	   ExpectLightsUnchanged();
                                                                                                                                   }

                                                                                                                                   TEST(LightScheduler, light_changed_at_the_right_time)
                                                                                                                                   {
                                                                                                                                       LightScheduler_ScheduleTurnOn(3, EVERYDAY, 1200);
                                                                                                                                       TransitionClockTo(SUNDAY, 1200);
                                                                                                                                       ExpectLightOn(3);
                                                                                                                                   }




                                                                                    www.renaissancesoftware.net                                                                                                www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                           james@renaissancesoftware.net   45   Copyright © 2008-2012 James W. Grenning                                               james@renaissancesoftware.net   46
All Rights Reserved. For use by training attendees.   Agile 2012, Grapevine, TX          basv@odd-e.com                All Rights Reserved. For use by training attendees.       Agile 2012, Grapevine, TX          basv@odd-e.com




                                                                                                                                                                     Replacing collaborators
                                                                                                                                        • Linker-stubbing
                             Test-Double Substitution                                                                                   • Function pointer
                                                                                                                                        • Pre-processor
                                    Options




                                                                                    www.renaissancesoftware.net                                                                                                www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                           james@renaissancesoftware.net   47   Copyright © 2008-2012 James W. Grenning                                               james@renaissancesoftware.net   48
All Rights Reserved. For use by training attendees.   Agile 2012, Grapevine, TX          basv@odd-e.com                All Rights Reserved. For use by training attendees.       Agile 2012, Grapevine, TX          basv@odd-e.com
Linker Stubbing
                                                                                                                                #include "sqlite3.h"

                                                                                                                                int sqlite3_open(const char *filename, sqlite3 **ppDb)
                                                                                                                                {
                                                                                                                                	    FAIL("sqlite3_open");
                                                                                                                                	    return 0;
                                                                                                                                }



                                           Linker Substitution                                                                  int sqlite3_step(sqlite3_stmt*)
                                                                                                                                {
                                                                                                                                	
                                                                                                                                	
                                                                                                                                     FAIL("sqlite3_step");
                                                                                                                                     return 0;
                                                                                                                                }
                                                                                                                                                                                                                Don’t link the real library.
                                                                                                                                int sqlite3_reset(sqlite3_stmt *pStmt)
                                                                                                                                {                                                                               Instead provide a fake
                                                                                                                                	
                                                                                                                                	
                                                                                                                                     FAIL("sqlite3_reset");
                                                                                                                                     return 0;                                                                  that does something
                                                                                                                                }

                                                                                                                                sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*)
                                                                                                                                                                                                                useful for the test
                                                                                                                                {
                                                                                                                                	    FAIL("sqlite3_last_insert_rowid");
                                                                                                                                	    return 0;
                                                                                                                                }

                                                                                                                                int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64)
                                                                                                                                {
                                                                                                                                	    FAIL("sqlite3_bind_int64");
                                                                                                                                	    return 0;
                                                                                                                                }



                                                                                        www.renaissancesoftware.net                                                                                                      www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                               james@renaissancesoftware.net   49   Copyright © 2008-2012 James W. Grenning                                                     james@renaissancesoftware.net   50
All Rights Reserved. For use by training attendees.   Agile 2012, Grapevine, TX              basv@odd-e.com                All Rights Reserved. For use by training attendees.      Agile 2012, Grapevine, TX                 basv@odd-e.com




                        Use linker stubs across subsystems

                                                      Interface                   TinyXML
                                                                                                                                             Function Pointer Substitution
   • Use linker stubs on other
                                                                                  Sqlite
       subsystems
   •   Linker stubs requires no
       change in code!
                                                      Engine                      dbus
                                           ✔                                      fzshelltext

                                                                                  putty
                                                                                        www.renaissancesoftware.net                                                                                                      www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                               james@renaissancesoftware.net   51   Copyright © 2008-2012 James W. Grenning                                                     james@renaissancesoftware.net   52
All Rights Reserved. For use by training attendees.   Agile 2012, Grapevine, TX              basv@odd-e.com                All Rights Reserved. For use by training attendees.      Agile 2012, Grapevine, TX                 basv@odd-e.com
Reasons to Use Function Pointers for
                                                                                                                                                    Example Usage - Printed Output
                               Test-Doubles
             • When you already use function pointers for other                                                                     • Logs and printed output are helpful for checking
               purposes (you have a built-in test hook!)                                                                              program correctness and debugging
                   – Swappable device drivers                                                                                       • But...
                   – Swappable implementations                                                                                            – They require that you look at the output.
             • You need the production implementation in the test                                                                         – They doom you to a lifetime of manually verified tests
               build, and you must substitute a test double in the                                                                  • So...
               same test build                                                                                                            – Design your code so that printed output can be captured
                   – printf                                                                                                                 and verified in your unit tests
             • You don’t want to have too many test builds due to
               using link-time substitution

                                                                                    www.renaissancesoftware.net                                                                                            www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                           james@renaissancesoftware.net   53   Copyright © 2008-2012 James W. Grenning                                           james@renaissancesoftware.net   54
All Rights Reserved. For use by training attendees.   Agile 2012, Grapevine, TX          basv@odd-e.com                All Rights Reserved. For use by training attendees.   Agile 2012, Grapevine, TX          basv@odd-e.com




                                    Manual/Tedious/Error Prone                                                                                               Function Pointer - Runtime
                                        Output Inspection                                                                                                           Substitution
                                                                                                                                   • Sometimes we want to use the real function.
                                                                                                                                   • Sometimes we want to use a test version.
                                                                                                                                   • Define a function pointer that has the same
                                                                                                                                     declaration as the function to override, in this case
                                                                                                                                     printf()
                                                                                                                                   #ifndef D_FormatOutput_H
                                                                                                                                   #define D_FormatOutput_H

                                                                                                                                   extern int (*FormatOutput)(const char *, ...);

                                                                                                                                   #endif // D_FormatOutput_H


                                                                                    www.renaissancesoftware.net                                                                                            www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                           james@renaissancesoftware.net   55   Copyright © 2008-2012 James W. Grenning                                           james@renaissancesoftware.net   56
All Rights Reserved. For use by training attendees.   Agile 2012, Grapevine, TX          basv@odd-e.com                All Rights Reserved. For use by training attendees.   Agile 2012, Grapevine, TX          basv@odd-e.com
By default, FormatOutput points to the                                                                                                                   Production Code
                                                        printf                                                                      Before:
                                                                                                                                   void someProductionCode()
                                                                                                                                   {
                                                                                                                                       printf(“hello %sn”, “world”);
            //FormatOutput.c                                                                                                       }
            #include "FormatOutput.h"
            #include <stdio.h>
                                                                                                                                    After:
            int (*FormatOutput)(const char* format, ...) = printf;                                                                 #include "FormatOutput.h"

                                                                                                                                   . . . . .

                                                                                                                                   void someProductionCode()
                                                                                                                                   {
                                                                                                                                       FormatOutput(“hello %sn”, “world”);
                                                                                                                                   }

                                                                                    www.renaissancesoftware.net                                                                                               www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                           james@renaissancesoftware.net   57   Copyright © 2008-2012 James W. Grenning                                              james@renaissancesoftware.net   58
All Rights Reserved. For use by training attendees.   Agile 2012, Grapevine, TX          basv@odd-e.com                All Rights Reserved. For use by training attendees.      Agile 2012, Grapevine, TX          basv@odd-e.com




                                            Runtime Substitution
                                                                                                                                                                             UT_PTR_SET
                                           Test setup and teardown
            • We can override the function by assigning the test                                                                          • CppUTest has a mechanism for overriding and
              version of the function during setup                                                                                          restoring pointers that must be restored after each
            • Don’t forget to restore the original                                                                                          test.
               • How should I do this more safely?                                                                                        • UT_PTR_SET() assigns the pointer and restores the
                                                                                                                                            original function pointer after teardown()
            void setup()
            {
                                                                                                                                   void setup()
                FormatOutput = FormatOutputSpy;
                                                                                                                                   {
            }
                                                                                                                                       UT_PTR_SET(FormatOutput, FormatOutputSpy);
                                                                                                                                   }
            void teardown()
            {
                                                                                                                                   void teardown()
                FormatOutput = printf;
                                                                                                                                   {
            }
                                                                                                                                   }
                                                                                    www.renaissancesoftware.net                                                                                               www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                           james@renaissancesoftware.net   59   Copyright © 2008-2012 James W. Grenning                                              james@renaissancesoftware.net   60
All Rights Reserved. For use by training attendees.   Agile 2012, Grapevine, TX          basv@odd-e.com                All Rights Reserved. For use by training attendees.      Agile 2012, Grapevine, TX          basv@odd-e.com
Sometime we Write Tests for Test Code                                                                                                                     Spy Overflow
                                             We must be able to trust the spy.
                                                Tests are documentation!

            TEST(FormatOutput, ATestThatPrintsThings)                                                                              TEST(FormatOutput, LimitTheOutputBufferSize)
            {                                                                                                                      {
                FormatOutputSpy_Create(20);                                                                                            FormatOutputSpy_Create(4);
                FormatOutput("Hello, Worldn");                                                                                        FormatOutput("Hello, Worldn");
                STRCMP_EQUAL("Hello, Worldn",                                                                                         STRCMP_EQUAL("Hell", FormatOutputSpy_GetOutput());
                        FormatOutputSpy_GetOutput());                                                                              }
            }




                                                                                    www.renaissancesoftware.net                                                                                             www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                           james@renaissancesoftware.net   61   Copyright © 2008-2012 James W. Grenning                                            james@renaissancesoftware.net   62
All Rights Reserved. For use by training attendees.   Agile 2012, Grapevine, TX          basv@odd-e.com                All Rights Reserved. For use by training attendees.    Agile 2012, Grapevine, TX          basv@odd-e.com




                                      More Checking on our Spy                                                                                                         Spying on the Output

                                                                                                                                   TEST(CircularBufferPrint, PrintNotYetWrappedOrFull)
                                                                                                                                   {
                                                                                                                                       CircularBuffer_Put(buffer, 10);
            TEST(FormatOutput, PrintMultipleTimes)                                                                                     CircularBuffer_Put(buffer, 20);
            {                                                                                                                          CircularBuffer_Put(buffer, 30);
                FormatOutputSpy_Create(25);                                                                                            CircularBuffer_Print(buffer);
                FormatOutput("Hello");
                FormatOutput(", Worldn");                                                                                                   expectedOutput = "Circular buffer content:n<10, 20, 30>n";
                STRCMP_EQUAL("Hello, Worldn",                                                                                               STRCMP_EQUAL(expectedOutput, FormatOutputSpy_GetOutput());
                                FormatOutputSpy_GetOutput());                                                                      }
            }




                                                                                    www.renaissancesoftware.net                                                                                             www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                           james@renaissancesoftware.net   63   Copyright © 2008-2012 James W. Grenning                                            james@renaissancesoftware.net   64
All Rights Reserved. For use by training attendees.   Agile 2012, Grapevine, TX          basv@odd-e.com                All Rights Reserved. For use by training attendees.    Agile 2012, Grapevine, TX          basv@odd-e.com
Test Fixture
            TEST_GROUP(CircularBufferPrint)
            {
                CircularBuffer buffer;
                const char * expectedOutput;
                const char * actualOutput;
                                                                                                                                                  Preprocessor Substitution
                    void setup()
                    {
                      UT_PTR_SET(FormatOutput, FormatOutputSpy);
                      FormatOutputSpy_Create(100);
                      buffer = CircularBuffer_Create(10);
                    }

                    void teardown()
                    {
                       CircularBuffer_Destroy(buffer);
                       FormatOutputSpy_Destroy();
                    }
            };

                                                                                     www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                            james@renaissancesoftware.net   65   Copyright © 2008-2012 James W. Grenning                                             www.renaissancesoftware.net   66
All Rights Reserved. For use by training attendees.    Agile 2012, Grapevine, TX          basv@odd-e.com                All Rights Reserved. For use by training attendees.   Agile 2012, Grapevine, TX   james@renaissancesoftware.net




                                         Preprocessor Substitution                                                                               Preprocessor Substitution Variants

             • Is the least desirable form of substitution                                                                           • Header file test double
             • Though necessary when                                                                                                       – Change the include path during test builds
                   – Header files won’t compile off-target                                                                           • Force includes
                   – Header files have are the start to a massive dependency                                                               – Force in a header file that substitutes problem
                     chain                                                                                                                   dependencies
                   – A direct function call API cannot be changed and you                                                            • Command line definition
                     need to override the direct call and use the direct call in                                                           – Override a symbol one at a time
                     the implementation of the fake
                          e.g. malloc(), free()




                                                                                     www.renaissancesoftware.net                                                                                            www.renaissancesoftware.net
Copyright © 2008-2012 James W. Grenning                                            james@renaissancesoftware.net   67   Copyright © 2008-2012 James W. Grenning                                           james@renaissancesoftware.net   68
All Rights Reserved. For use by training attendees.    Agile 2012, Grapevine, TX          basv@odd-e.com                All Rights Reserved. For use by training attendees.   Agile 2012, Grapevine, TX          basv@odd-e.com
Tdd ec-agile2012
Tdd ec-agile2012
Tdd ec-agile2012
Tdd ec-agile2012
Tdd ec-agile2012
Tdd ec-agile2012
Tdd ec-agile2012
Tdd ec-agile2012
Tdd ec-agile2012
Tdd ec-agile2012
Tdd ec-agile2012

Weitere ähnliche Inhalte

Ähnlich wie Tdd ec-agile2012

Tim Klein's talk on making websites with SilverStripe in no time
Tim Klein's talk on making websites with SilverStripe in no timeTim Klein's talk on making websites with SilverStripe in no time
Tim Klein's talk on making websites with SilverStripe in no timeJoannaTMcLeod
 
Redistributable introtoscrum
Redistributable introtoscrumRedistributable introtoscrum
Redistributable introtoscrumCiklum Ukraine
 
Dancing about architecture
Dancing about architectureDancing about architecture
Dancing about architectureCoraline Ehmke
 
Introduction to Agile and Scrum (Montana Programmers Meetup Jan 2012).pptx
Introduction to Agile and Scrum (Montana Programmers Meetup Jan 2012).pptxIntroduction to Agile and Scrum (Montana Programmers Meetup Jan 2012).pptx
Introduction to Agile and Scrum (Montana Programmers Meetup Jan 2012).pptxDesigned Culture
 
Webinar: Scaling MongoDB through Sharding - A Case Study with CIGNEX Datamatics
Webinar: Scaling MongoDB through Sharding - A Case Study with CIGNEX DatamaticsWebinar: Scaling MongoDB through Sharding - A Case Study with CIGNEX Datamatics
Webinar: Scaling MongoDB through Sharding - A Case Study with CIGNEX DatamaticsMongoDB
 
DAT320_Moving a Galaxy into Cloud
DAT320_Moving a Galaxy into CloudDAT320_Moving a Galaxy into Cloud
DAT320_Moving a Galaxy into CloudAmazon Web Services
 
Short agilefordba
Short agilefordbaShort agilefordba
Short agilefordbaShane Hayes
 
Feature Prioritization Rmpdma Public
Feature Prioritization Rmpdma PublicFeature Prioritization Rmpdma Public
Feature Prioritization Rmpdma PublicSignarama Dtc
 
Introduction To Agile
Introduction To AgileIntroduction To Agile
Introduction To AgileTony Deng
 
AWS Meetup - Sydney - February
AWS Meetup - Sydney - February AWS Meetup - Sydney - February
AWS Meetup - Sydney - February markghiasy
 
Real Life WebSocket Case Studies and Demos
Real Life WebSocket Case Studies and DemosReal Life WebSocket Case Studies and Demos
Real Life WebSocket Case Studies and DemosPeter Moskovits
 
Mongo Seattle - The Business of MongoDB
Mongo Seattle - The Business of MongoDBMongo Seattle - The Business of MongoDB
Mongo Seattle - The Business of MongoDBJustin Smestad
 
Open Source Managed Databases: Database Week SF
Open Source Managed Databases: Database Week SFOpen Source Managed Databases: Database Week SF
Open Source Managed Databases: Database Week SFAmazon Web Services
 
Metrics-Driven Performance Tuning for AWS Glue ETL Jobs (ANT326) - AWS re:Inv...
Metrics-Driven Performance Tuning for AWS Glue ETL Jobs (ANT326) - AWS re:Inv...Metrics-Driven Performance Tuning for AWS Glue ETL Jobs (ANT326) - AWS re:Inv...
Metrics-Driven Performance Tuning for AWS Glue ETL Jobs (ANT326) - AWS re:Inv...Amazon Web Services
 
Lean & agile 101 for Astute Entrepreneurs
Lean & agile 101 for Astute EntrepreneursLean & agile 101 for Astute Entrepreneurs
Lean & agile 101 for Astute EntrepreneursClaudio Perrone
 
Seo training-2010-100818134052-phpapp02
Seo training-2010-100818134052-phpapp02Seo training-2010-100818134052-phpapp02
Seo training-2010-100818134052-phpapp02Javier Romero Alonso
 

Ähnlich wie Tdd ec-agile2012 (20)

Tim Klein's talk on making websites with SilverStripe in no time
Tim Klein's talk on making websites with SilverStripe in no timeTim Klein's talk on making websites with SilverStripe in no time
Tim Klein's talk on making websites with SilverStripe in no time
 
Redistributable introtoscrum
Redistributable introtoscrumRedistributable introtoscrum
Redistributable introtoscrum
 
Dancing about architecture
Dancing about architectureDancing about architecture
Dancing about architecture
 
Introduction to Agile and Scrum (Montana Programmers Meetup Jan 2012).pptx
Introduction to Agile and Scrum (Montana Programmers Meetup Jan 2012).pptxIntroduction to Agile and Scrum (Montana Programmers Meetup Jan 2012).pptx
Introduction to Agile and Scrum (Montana Programmers Meetup Jan 2012).pptx
 
Webinar: Scaling MongoDB through Sharding - A Case Study with CIGNEX Datamatics
Webinar: Scaling MongoDB through Sharding - A Case Study with CIGNEX DatamaticsWebinar: Scaling MongoDB through Sharding - A Case Study with CIGNEX Datamatics
Webinar: Scaling MongoDB through Sharding - A Case Study with CIGNEX Datamatics
 
DAT320_Moving a Galaxy into Cloud
DAT320_Moving a Galaxy into CloudDAT320_Moving a Galaxy into Cloud
DAT320_Moving a Galaxy into Cloud
 
Short agilefordba
Short agilefordbaShort agilefordba
Short agilefordba
 
Feature Prioritization Rmpdma Public
Feature Prioritization Rmpdma PublicFeature Prioritization Rmpdma Public
Feature Prioritization Rmpdma Public
 
Introduction To Agile
Introduction To AgileIntroduction To Agile
Introduction To Agile
 
AWS Meetup - Sydney - February
AWS Meetup - Sydney - February AWS Meetup - Sydney - February
AWS Meetup - Sydney - February
 
Real Life WebSocket Case Studies and Demos
Real Life WebSocket Case Studies and DemosReal Life WebSocket Case Studies and Demos
Real Life WebSocket Case Studies and Demos
 
Magic of scrum with SAP
Magic of scrum with SAPMagic of scrum with SAP
Magic of scrum with SAP
 
Mongo Seattle - The Business of MongoDB
Mongo Seattle - The Business of MongoDBMongo Seattle - The Business of MongoDB
Mongo Seattle - The Business of MongoDB
 
Open Source Managed Databases: Database Week SF
Open Source Managed Databases: Database Week SFOpen Source Managed Databases: Database Week SF
Open Source Managed Databases: Database Week SF
 
Kanban Case Study
Kanban Case StudyKanban Case Study
Kanban Case Study
 
Metrics-Driven Performance Tuning for AWS Glue ETL Jobs (ANT326) - AWS re:Inv...
Metrics-Driven Performance Tuning for AWS Glue ETL Jobs (ANT326) - AWS re:Inv...Metrics-Driven Performance Tuning for AWS Glue ETL Jobs (ANT326) - AWS re:Inv...
Metrics-Driven Performance Tuning for AWS Glue ETL Jobs (ANT326) - AWS re:Inv...
 
Lean & agile 101 for Astute Entrepreneurs
Lean & agile 101 for Astute EntrepreneursLean & agile 101 for Astute Entrepreneurs
Lean & agile 101 for Astute Entrepreneurs
 
Seo training-2010-100818134052-phpapp02
Seo training-2010-100818134052-phpapp02Seo training-2010-100818134052-phpapp02
Seo training-2010-100818134052-phpapp02
 
Seo training
Seo trainingSeo training
Seo training
 
SEO Introduction
SEO IntroductionSEO Introduction
SEO Introduction
 

Mehr von drewz lin

Web security-–-everything-we-know-is-wrong-eoin-keary
Web security-–-everything-we-know-is-wrong-eoin-kearyWeb security-–-everything-we-know-is-wrong-eoin-keary
Web security-–-everything-we-know-is-wrong-eoin-kearydrewz lin
 
Phu appsec13
Phu appsec13Phu appsec13
Phu appsec13drewz lin
 
Owasp advanced mobile-application-code-review-techniques-v0.2
Owasp advanced mobile-application-code-review-techniques-v0.2Owasp advanced mobile-application-code-review-techniques-v0.2
Owasp advanced mobile-application-code-review-techniques-v0.2drewz lin
 
I mas appsecusa-nov13-v2
I mas appsecusa-nov13-v2I mas appsecusa-nov13-v2
I mas appsecusa-nov13-v2drewz lin
 
Defeating xss-and-xsrf-with-my faces-frameworks-steve-wolf
Defeating xss-and-xsrf-with-my faces-frameworks-steve-wolfDefeating xss-and-xsrf-with-my faces-frameworks-steve-wolf
Defeating xss-and-xsrf-with-my faces-frameworks-steve-wolfdrewz lin
 
Csrf not-all-defenses-are-created-equal
Csrf not-all-defenses-are-created-equalCsrf not-all-defenses-are-created-equal
Csrf not-all-defenses-are-created-equaldrewz lin
 
Chuck willis-owaspbwa-beyond-1.0-app secusa-2013-11-21
Chuck willis-owaspbwa-beyond-1.0-app secusa-2013-11-21Chuck willis-owaspbwa-beyond-1.0-app secusa-2013-11-21
Chuck willis-owaspbwa-beyond-1.0-app secusa-2013-11-21drewz lin
 
Appsec usa roberthansen
Appsec usa roberthansenAppsec usa roberthansen
Appsec usa roberthansendrewz lin
 
Appsec usa2013 js_libinsecurity_stefanodipaola
Appsec usa2013 js_libinsecurity_stefanodipaolaAppsec usa2013 js_libinsecurity_stefanodipaola
Appsec usa2013 js_libinsecurity_stefanodipaoladrewz lin
 
Appsec2013 presentation-dickson final-with_all_final_edits
Appsec2013 presentation-dickson final-with_all_final_editsAppsec2013 presentation-dickson final-with_all_final_edits
Appsec2013 presentation-dickson final-with_all_final_editsdrewz lin
 
Appsec2013 presentation
Appsec2013 presentationAppsec2013 presentation
Appsec2013 presentationdrewz lin
 
Appsec 2013-krehel-ondrej-forensic-investigations-of-web-exploitations
Appsec 2013-krehel-ondrej-forensic-investigations-of-web-exploitationsAppsec 2013-krehel-ondrej-forensic-investigations-of-web-exploitations
Appsec 2013-krehel-ondrej-forensic-investigations-of-web-exploitationsdrewz lin
 
Appsec2013 assurance tagging-robert martin
Appsec2013 assurance tagging-robert martinAppsec2013 assurance tagging-robert martin
Appsec2013 assurance tagging-robert martindrewz lin
 
Amol scadaowasp
Amol scadaowaspAmol scadaowasp
Amol scadaowaspdrewz lin
 
Agile sdlc-v1.1-owasp-app sec-usa
Agile sdlc-v1.1-owasp-app sec-usaAgile sdlc-v1.1-owasp-app sec-usa
Agile sdlc-v1.1-owasp-app sec-usadrewz lin
 
Vulnex app secusa2013
Vulnex app secusa2013Vulnex app secusa2013
Vulnex app secusa2013drewz lin
 
基于虚拟化技术的分布式软件测试框架
基于虚拟化技术的分布式软件测试框架基于虚拟化技术的分布式软件测试框架
基于虚拟化技术的分布式软件测试框架drewz lin
 
新浪微博稳定性经验谈
新浪微博稳定性经验谈新浪微博稳定性经验谈
新浪微博稳定性经验谈drewz lin
 
无线App的性能分析和监控实践 rickyqiu
无线App的性能分析和监控实践 rickyqiu无线App的性能分析和监控实践 rickyqiu
无线App的性能分析和监控实践 rickyqiudrewz lin
 
网易移动自动化测试实践(孔庆云)
网易移动自动化测试实践(孔庆云)网易移动自动化测试实践(孔庆云)
网易移动自动化测试实践(孔庆云)drewz lin
 

Mehr von drewz lin (20)

Web security-–-everything-we-know-is-wrong-eoin-keary
Web security-–-everything-we-know-is-wrong-eoin-kearyWeb security-–-everything-we-know-is-wrong-eoin-keary
Web security-–-everything-we-know-is-wrong-eoin-keary
 
Phu appsec13
Phu appsec13Phu appsec13
Phu appsec13
 
Owasp advanced mobile-application-code-review-techniques-v0.2
Owasp advanced mobile-application-code-review-techniques-v0.2Owasp advanced mobile-application-code-review-techniques-v0.2
Owasp advanced mobile-application-code-review-techniques-v0.2
 
I mas appsecusa-nov13-v2
I mas appsecusa-nov13-v2I mas appsecusa-nov13-v2
I mas appsecusa-nov13-v2
 
Defeating xss-and-xsrf-with-my faces-frameworks-steve-wolf
Defeating xss-and-xsrf-with-my faces-frameworks-steve-wolfDefeating xss-and-xsrf-with-my faces-frameworks-steve-wolf
Defeating xss-and-xsrf-with-my faces-frameworks-steve-wolf
 
Csrf not-all-defenses-are-created-equal
Csrf not-all-defenses-are-created-equalCsrf not-all-defenses-are-created-equal
Csrf not-all-defenses-are-created-equal
 
Chuck willis-owaspbwa-beyond-1.0-app secusa-2013-11-21
Chuck willis-owaspbwa-beyond-1.0-app secusa-2013-11-21Chuck willis-owaspbwa-beyond-1.0-app secusa-2013-11-21
Chuck willis-owaspbwa-beyond-1.0-app secusa-2013-11-21
 
Appsec usa roberthansen
Appsec usa roberthansenAppsec usa roberthansen
Appsec usa roberthansen
 
Appsec usa2013 js_libinsecurity_stefanodipaola
Appsec usa2013 js_libinsecurity_stefanodipaolaAppsec usa2013 js_libinsecurity_stefanodipaola
Appsec usa2013 js_libinsecurity_stefanodipaola
 
Appsec2013 presentation-dickson final-with_all_final_edits
Appsec2013 presentation-dickson final-with_all_final_editsAppsec2013 presentation-dickson final-with_all_final_edits
Appsec2013 presentation-dickson final-with_all_final_edits
 
Appsec2013 presentation
Appsec2013 presentationAppsec2013 presentation
Appsec2013 presentation
 
Appsec 2013-krehel-ondrej-forensic-investigations-of-web-exploitations
Appsec 2013-krehel-ondrej-forensic-investigations-of-web-exploitationsAppsec 2013-krehel-ondrej-forensic-investigations-of-web-exploitations
Appsec 2013-krehel-ondrej-forensic-investigations-of-web-exploitations
 
Appsec2013 assurance tagging-robert martin
Appsec2013 assurance tagging-robert martinAppsec2013 assurance tagging-robert martin
Appsec2013 assurance tagging-robert martin
 
Amol scadaowasp
Amol scadaowaspAmol scadaowasp
Amol scadaowasp
 
Agile sdlc-v1.1-owasp-app sec-usa
Agile sdlc-v1.1-owasp-app sec-usaAgile sdlc-v1.1-owasp-app sec-usa
Agile sdlc-v1.1-owasp-app sec-usa
 
Vulnex app secusa2013
Vulnex app secusa2013Vulnex app secusa2013
Vulnex app secusa2013
 
基于虚拟化技术的分布式软件测试框架
基于虚拟化技术的分布式软件测试框架基于虚拟化技术的分布式软件测试框架
基于虚拟化技术的分布式软件测试框架
 
新浪微博稳定性经验谈
新浪微博稳定性经验谈新浪微博稳定性经验谈
新浪微博稳定性经验谈
 
无线App的性能分析和监控实践 rickyqiu
无线App的性能分析和监控实践 rickyqiu无线App的性能分析和监控实践 rickyqiu
无线App的性能分析和监控实践 rickyqiu
 
网易移动自动化测试实践(孔庆云)
网易移动自动化测试实践(孔庆云)网易移动自动化测试实践(孔庆云)
网易移动自动化测试实践(孔庆云)
 

Tdd ec-agile2012

  • 1. Topics TDD for Embedded C Talk to us on Twitter http://twitter.com/jwgrenning • The why and what of TDD http://twitter.com/basvodde • Embedded adaptation Find us on linkedin.com • Abstracting HW and OS http://www.linkedin.com/in/jwgrenning http://www.linkedin.com/in/basvodde • Mocking the silicon Remind us how we met. • Test-double substitution options http://www.renaissancesoftware.net http:// www.jamesgrenning.com Scaling Lean & Agile Practices for Scaling Lean & Agile • Function pointer substitution Development Development http://www.odd-e.com Thinking and Organizational Tools for Large-Scale Scrum Craig Larman Bas Vodde Large, Multisite, and Offshore Products with Large-Scale Scrum Craig Larman Bas Vodde • Preprocessor substitution • TDD next to an RTOS Come to a full version of James’ TDD for Embedded C October 2012. Phoenix, AZ www.renaissancesoftware.net www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 1 Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 2 All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com This Work Flow is Designed to Allow Defects Why TDD? What is TDD? Development Test Defects www.renaissancesoftware.net www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 3 Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 4 All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com
  • 2. The Physics of Debug Later Your program will have Programming (DLP) bugs. And they will surprise you when you Td Tfind T fix find them. Time Mistake made Bug discovery (bug injection) Bug found Bug fixed • As Td increases, Tfind increases dramatically • Tfix is usually short, but can increase with Td www.renaissancesoftware.net www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 5 Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 6 All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com A Bug’s Life Edsger Dijkstra Those who want really reliable software will discover that they must find means of avoiding the majority of bugs to start with, and as a result, the programming process will become cheaper. If you want more effective programmers, you will discover that they should not waste their time debugging, they should not introduce the bugs to start with. From http://www.softwaretestinghelp.com/bug-life-cycle/ www.renaissancesoftware.net www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 7 Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 8 All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com All Rights Reserved. For use by training attendees. basv@odd-e.com
  • 3. Can we Realize Being g Dijkstra’s Dream and ood at c is not T hasing Prevent Defects with echnica bugs l Excelle Test Driven Development? nce www.renaissancesoftware.net www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 9 Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 10 All Rights Reserved. For use by training attendees. basv@odd-e.com All Rights Reserved. For use by training attendees. basv@odd-e.com Development and Test Work Together Preventing Defects A Complex system that works is invariably found to have evolved from a simple system Development that worked. Test www.renaissancesoftware.net www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 11 Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 12 All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com
  • 4. The Physics of Test Driven Why is it difficult to sustain? Development T d Tfind T fix Time Mistake Mistake fixed made Mistake Root cause discovery found • When Td approaches zero, Tfind approaches zero TDD: Traditional: • In many cases, bugs are not around long enough to be considered • Steady pace • Spurts bugs. • Speed limits • Fast when no problems! • See: http://www.renaissancesoftware.net/blog/archives/16 • No traffic lights (bugs) • Debugging • Might feel slow!! • Feels fast! But often slow www.renaissancesoftware.net www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 13 Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 14 All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com Sustainability Time developers do not notice nor plan for Traditional Speculate Code Test Debug development Demo and Exercise Time vs Feels slower Test-driven Spec development ulate Test and Code Debug www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 15 Copyright © 2008-2012 James W. Grenning www.renaissancesoftware.net 16 All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX james@renaissancesoftware.net
  • 5. Cheat sheet /* in CheatSheetTest.cpp */ #include "CppUTest/TestHarness.h" /* Declare TestGroup with name CheatSheet */ TEST_GROUP(CheatSheet) { /* declare a setup method for the test group. Optional. */ void setup () CppUTest Quick Intro { /* Set method real_one to stub. Automatically restore in teardown */ UT_PTR_SET(real_one, stub); } /* Declare a teardown method for the test group. Optional */ void teardown() { } }; /* Do not forget semicolumn */ /* In allTest.cpp */ IMPORT_TEST_GROUP(CheatSheet); /* Declare one test within the test group */ TEST(CheatSheet, TestName) /* In main.cpp */ { /* Check two longs are equal */ #include "CppUTest/CommandLineTestRunner.h" LONGS_EQUAL(1, 1); #include "AllTests.h" /* Check a condition */ int main(int ac, char** av) CHECK(true); { return CommandLineTestRunner::RunAllTests(ac, av); /* Check a string */ } STRCMP_EQUAL("HelloWorld", "HelloWorld"); } www.renaissancesoftware.net www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 17 Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 18 All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com Test Fixture Output Format Data needed in each test. TEST_GROUP(TemplateEngineTest) Run before { each test No news is good news Template aTemplate; TemplatePlaceholderValues replacementValues; ./TestFirst EmailFormatter *emailFormat; . void setup() { OK (1 tests, 1 ran, 1 checks, 0 ignored, 0 filtered out, 0 ms) emailFormatter = createMockFormatter(); aTemplate.setEmailFormat(emailFormat); The data and } void teardown(){ Give precise information when fails destroyFormatter(emailFormatter); ./TestFirst setup / teardown } is also }; Run after TestFirst.cpp:10: error: Failure in TEST(FirstTest, First) make: *** [all] Error 1 sometimes TEST(TemplateEngineTest, templatesWithoutPlaceHoldersDoNotChange) each test expected <1 0x1> called: { but was <0 0x0> test fixture aTemplate.set("Nothing here"); STRCMP_EQUAL("Nothing here", . Errors (1 failures, 1 tests, 1 ran, 1 checks, 0 ignored, 0 filtered out, 0 ms) aTemplate.replaceValues(replacementValues).c_str()); } www.renaissancesoftware.net www.renaissancesoftware.net 49 Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 19 Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 20 All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com
  • 6. More info • CppUTest Github Project page: – http://cpputest.github.com/cpputest/ Adaptation for Embedded • The CppUTest Github repository: Software – https://github.com/cpputest/cpputest • The CppUTest Man page: – http://www.cpputest.org/ www.renaissancesoftware.net www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 21 Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 22 All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com What are the special What is special about embedded challenges you have over a • Concurrent HW development non-embedded developer? • HW bottleneck • Cross compilation • Limited memory and IO • Target debug • Architecture www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning www.renaissancesoftware.net 23 Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 24 All Rights Reserved. For use by training attendees. james@renaissancesoftware.net All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com
  • 7. Hardware is Scarce! • It does not exist. • It is being used by someone else. • It has bugs of its own. www.renaissancesoftware.net www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 25 Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 26 All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com www.renaissancesoftware.net www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 27 Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 28 All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com All Rights Reserved. For use by training attendees. basv@odd-e.com
  • 8. Minimize DoH! Debug on Copyright Fox Broadcasting. Used under fair use. Hardware www.renaissancesoftware.net www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 29 Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 30 All Rights Reserved. For use by training attendees. basv@odd-e.com All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com Why Use Your Development System How to Use Your Development for a Test Bed? System for a Test Bed? • Waiting for hardware. • Multi-targeted code. • Waiting for restart. • Must make code portable • Waiting for downloads. • Must beware of hardware and OS dependencies. • Waiting for long compiles. • Object Oriented approach to Dependency • Debugging on the target. Management. • Target has bugs. • (Re)Configuring the lab Avoid wasteful practices www.renaissancesoftware.net www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 31 Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 32 All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com
  • 9. But There are Risks with TDD Adaptation for Embedded Development System Tests Development • Architecture differences Stage 1 Stage 2 Stage 3 Stage 4 Stage 5 – Word size – Big-endian Little-endian – Alignment Write a Test Compile Run Tests Run Tests Acceptance Make it Pass for Target in the Eval in Target Tests • Compiler differences Refactor Processor Hardware Hardware • Library differences • Execution differences More Frequent Less Frequent www.renaissancesoftware.net www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 33 Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 34 All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com TDD Adaptation for Embedded Continuous Integration - Embedded Development 3. CIS notices changes, refreshes its local copy, builds and runs host 2. Developer Stage 1 Stage 2 Stage 3 Stage 4 Stage 5 checks in work Source Code Continuous Integration Test Management regularly. Repository Server System 4. After successful host build/test, CIS Write a Test Compile Run Tests Run Tests Acceptance builds and hands Make it Pass for Target in the Eval in Target Tests images to TMS to deploy to Refactor Processor Hardware Hardware simulator, eval/ reference boards 1. Developer has or target system. all unit tests Eval/Reference More Frequent Less Frequent System Developer Simulator Target System Workstation See : http://renaissancesoftware.net/files/articles/ProgressBeforeHardware.pdf The SCR, CIS and TMS are not necessarily separate hardware systems. www.renaissancesoftware.net www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 35 Copyright © 2008-2012 James W. Grenning 35 james@renaissancesoftware.net All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com
  • 10. Problems Found at Appropriate Stage Stage Problems Likely to Find in Stage 1 Logic, design, modularity, interface, boundary conditions 2 Compiler compatibility (language features) Library compatibility (header files, declarations) Hardware and OS Abstraction 3 Processor executions problems (compiler and library bugs) Portability problems (word size, alignment, endian) 4 Ditto stage 3 Hardware integration problems Misunderstood hardware specifications 5 Ditto stage 4 Misunderstood feature specification www.renaissancesoftware.net www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 37 Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 38 All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com Separation of Responsibilities Light Scheduler Design • Every minute, the RTOS wakes up Admin Console Light Scheduler • Program to Admin Console Light Scheduler the Light +ScheduleTurnOn() Interfaces + ScheduleTurnOn() +RemoveSchedule() + RemoveSchedule() Scheduler. +WakeUp() <<anonymous callback>> • Separate interface +WakeUp() <<anonymous callback>> • If it is time for and implementation as separate entities. <<interface>> <<interface>> Light Controller Time Service one of the lights to + On(id) + GetTime() Light Controller + On(id) Time Service + GetTime() be controlled, the + Off(id) + SetPeriodicAlarm() • This design has + Off(id) + SetPeriodicAlarm() LightController is good separation of <<implements>> <<implements>> told to turn on/off Hardware RTOS responsibilities Model 42 RTOS Light Controller Time Service the light. Model 42 Hardware RTOS www.renaissancesoftware.net www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 39 Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 40 All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com
  • 11. LightScheduler Test Fixture Design Testing the Scheduler Light TEST(LightScheduler, light_not_changed_at_the_wrong_time) • Use the real Scheduler Light Scheduler { Test collaborators if + ScheduleTurnOn() LightScheduler_ScheduleTurnOn(3, EVERYDAY, 1200); FakeTimeService_SetMinute(1199); + RemoveSchedule() you can. +wakeUp() LightScheduler_Wakeup(); LONGS_EQUAL(NO_LIGHT_ID, LightControllerSpy_GetLastId()); • Use fakes when LONGS_EQUAL(LIGHT_STATE_UNKNOWN, LightControllerSpy_GetLastState()); } you must. <<interface>> Light Controller <<interface>> Time Service + On(id) + GetTime() TEST(LightScheduler, light_changed_at_the_right_time) + Off(id) + SetPeriodicAlarm() { LightScheduler_ScheduleTurnOn(3, EVERYDAY, 1200); FakeTimeService_SetMinute(1200); <<implements>> <<implements>> LightScheduler_Wakeup(); Light Controller Fake LONGS_EQUAL(3, LightControllerSpy_GetLastId()); Spy Time Service LONGS_EQUAL(LIGHT_ON, LightControllerSpy_GetLastState()); } www.renaissancesoftware.net www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 41 Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 42 All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com Light Scheduler Test List A Complex system that Light Scheduler Tests works is invariably Lights are not changed at initialization found to have evolved Time is wrong, day is wrong, no lights are changed Day is right, time is wrong, no lights are changed from a simple system Day is wrong, time is right, no lights are changed Day is right, time is right, the right light is turned on Day is right, time is right, the right light is turned off that worked. Schedule every day Schedule a specific day Schedule all weekdays Schedule weekend days Remove scheduled event Remove non-existent event Multiple scheduled events at the same time Multiple scheduled events for the same light Remove non scheduled light schedule Schedule the maximum supported number of events (128) Schedule too many events www.renaissancesoftware.net www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 43 Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 44 All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com
  • 12. Partial Skeleton Let’s Your Try the Copy/Paste THINK Design and Test Ideas Early TEST(LightScheduler, light_not_changed_at_the_wrong_time) { LightScheduler_ScheduleTurnOn(3, EVERYDAY, 1200); TransitionClockTo(SUNDAY, 1199); ExpectLightsUnchanged(); } TEST(LightScheduler, light_changed_at_the_right_time) { LightScheduler_ScheduleTurnOn(3, EVERYDAY, 1200); TransitionClockTo(SUNDAY, 1200); ExpectLightOn(3); } www.renaissancesoftware.net www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 45 Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 46 All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com Replacing collaborators • Linker-stubbing Test-Double Substitution • Function pointer • Pre-processor Options www.renaissancesoftware.net www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 47 Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 48 All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com
  • 13. Linker Stubbing #include "sqlite3.h" int sqlite3_open(const char *filename, sqlite3 **ppDb) { FAIL("sqlite3_open"); return 0; } Linker Substitution int sqlite3_step(sqlite3_stmt*) { FAIL("sqlite3_step"); return 0; } Don’t link the real library. int sqlite3_reset(sqlite3_stmt *pStmt) { Instead provide a fake FAIL("sqlite3_reset"); return 0; that does something } sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*) useful for the test { FAIL("sqlite3_last_insert_rowid"); return 0; } int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64) { FAIL("sqlite3_bind_int64"); return 0; } www.renaissancesoftware.net www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 49 Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 50 All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com Use linker stubs across subsystems Interface TinyXML Function Pointer Substitution • Use linker stubs on other Sqlite subsystems • Linker stubs requires no change in code! Engine dbus ✔ fzshelltext putty www.renaissancesoftware.net www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 51 Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 52 All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com
  • 14. Reasons to Use Function Pointers for Example Usage - Printed Output Test-Doubles • When you already use function pointers for other • Logs and printed output are helpful for checking purposes (you have a built-in test hook!) program correctness and debugging – Swappable device drivers • But... – Swappable implementations – They require that you look at the output. • You need the production implementation in the test – They doom you to a lifetime of manually verified tests build, and you must substitute a test double in the • So... same test build – Design your code so that printed output can be captured – printf and verified in your unit tests • You don’t want to have too many test builds due to using link-time substitution www.renaissancesoftware.net www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 53 Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 54 All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com Manual/Tedious/Error Prone Function Pointer - Runtime Output Inspection Substitution • Sometimes we want to use the real function. • Sometimes we want to use a test version. • Define a function pointer that has the same declaration as the function to override, in this case printf() #ifndef D_FormatOutput_H #define D_FormatOutput_H extern int (*FormatOutput)(const char *, ...); #endif // D_FormatOutput_H www.renaissancesoftware.net www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 55 Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 56 All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com
  • 15. By default, FormatOutput points to the Production Code printf Before: void someProductionCode() { printf(“hello %sn”, “world”); //FormatOutput.c } #include "FormatOutput.h" #include <stdio.h> After: int (*FormatOutput)(const char* format, ...) = printf; #include "FormatOutput.h" . . . . . void someProductionCode() { FormatOutput(“hello %sn”, “world”); } www.renaissancesoftware.net www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 57 Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 58 All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com Runtime Substitution UT_PTR_SET Test setup and teardown • We can override the function by assigning the test • CppUTest has a mechanism for overriding and version of the function during setup restoring pointers that must be restored after each • Don’t forget to restore the original test. • How should I do this more safely? • UT_PTR_SET() assigns the pointer and restores the original function pointer after teardown() void setup() { void setup() FormatOutput = FormatOutputSpy; { } UT_PTR_SET(FormatOutput, FormatOutputSpy); } void teardown() { void teardown() FormatOutput = printf; { } } www.renaissancesoftware.net www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 59 Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 60 All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com
  • 16. Sometime we Write Tests for Test Code Spy Overflow We must be able to trust the spy. Tests are documentation! TEST(FormatOutput, ATestThatPrintsThings) TEST(FormatOutput, LimitTheOutputBufferSize) { { FormatOutputSpy_Create(20); FormatOutputSpy_Create(4); FormatOutput("Hello, Worldn"); FormatOutput("Hello, Worldn"); STRCMP_EQUAL("Hello, Worldn", STRCMP_EQUAL("Hell", FormatOutputSpy_GetOutput()); FormatOutputSpy_GetOutput()); } } www.renaissancesoftware.net www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 61 Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 62 All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com More Checking on our Spy Spying on the Output TEST(CircularBufferPrint, PrintNotYetWrappedOrFull) { CircularBuffer_Put(buffer, 10); TEST(FormatOutput, PrintMultipleTimes) CircularBuffer_Put(buffer, 20); { CircularBuffer_Put(buffer, 30); FormatOutputSpy_Create(25); CircularBuffer_Print(buffer); FormatOutput("Hello"); FormatOutput(", Worldn"); expectedOutput = "Circular buffer content:n<10, 20, 30>n"; STRCMP_EQUAL("Hello, Worldn", STRCMP_EQUAL(expectedOutput, FormatOutputSpy_GetOutput()); FormatOutputSpy_GetOutput()); } } www.renaissancesoftware.net www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 63 Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 64 All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com
  • 17. Test Fixture TEST_GROUP(CircularBufferPrint) { CircularBuffer buffer; const char * expectedOutput; const char * actualOutput; Preprocessor Substitution void setup() { UT_PTR_SET(FormatOutput, FormatOutputSpy); FormatOutputSpy_Create(100); buffer = CircularBuffer_Create(10); } void teardown() { CircularBuffer_Destroy(buffer); FormatOutputSpy_Destroy(); } }; www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 65 Copyright © 2008-2012 James W. Grenning www.renaissancesoftware.net 66 All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX james@renaissancesoftware.net Preprocessor Substitution Preprocessor Substitution Variants • Is the least desirable form of substitution • Header file test double • Though necessary when – Change the include path during test builds – Header files won’t compile off-target • Force includes – Header files have are the start to a massive dependency – Force in a header file that substitutes problem chain dependencies – A direct function call API cannot be changed and you • Command line definition need to override the direct call and use the direct call in – Override a symbol one at a time the implementation of the fake e.g. malloc(), free() www.renaissancesoftware.net www.renaissancesoftware.net Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 67 Copyright © 2008-2012 James W. Grenning james@renaissancesoftware.net 68 All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com All Rights Reserved. For use by training attendees. Agile 2012, Grapevine, TX basv@odd-e.com