Dirty Tricks in the Name of Quality Ian Dees Tektronix - - PowerPoint PPT Presentation

dirty tricks in the name of quality
SMART_READER_LITE
LIVE PREVIEW

Dirty Tricks in the Name of Quality Ian Dees Tektronix - - PowerPoint PPT Presentation

Dirty Tricks in the Name of Quality Ian Dees Tektronix ian.s.dees@tek.com Hi, Im Ian. Im here to talk about dirty tricks in software construction.


slide-1
SLIDE 1 Dirty Tricks in the Name of Quality Ian Dees Tektronix ian.s.dees@tek.com Hi, I’m Ian. I’m here to talk about dirty tricks in software construction. ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 1
slide-2
SLIDE 2 What’s a dirty trick? Universal “best practice” Antipattern ≈ Mindful technical debt By “dirty trick,” I mean a practice that may be necessary in some contexts, but a terrible idea in others. Something like a small amount of technical debt we undertake mindfully. ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 2
slide-3
SLIDE 3 e.g., the Ghost Typo For example, a tester attending this conference told me her co-workers were ignoring e- mails about a draft document. But when she told them, “There’s a typo in your draft,” they suddenly paid attention to the substantive concerns she was raising. ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 3
slide-4
SLIDE 4 Your examples? These practices aren’t something you can get away with every time—but they may be just the trick to get you or your team unblocked. ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 4
slide-5
SLIDE 5 Why “Dirty Tricks?” I proposed this talk because our team just finished a big project. Afterwards, we reflected on what practices worked or didn’t work. A third category emerged: things that perhaps shouldn’t have worked, but did... this time. ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 5
slide-6
SLIDE 6 A Sampler
  • 0. The Meta-Dirty Trick
  • I. Blunt Code
  • II. Test Practices
III.Social Beings This isn’t one of those talks that features a case study or rich data. This talk is mainly a set of variations on a theme, loosely clustered into a few broad groups. ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 6
slide-7
SLIDE 7 The Meta-Dirty Trick: The first and most important trick—and the only one I’ll express in the imperative—is... ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 7
slide-8
SLIDE 8 DON’T GET FIRED ...don’t take the things in this talk as career advice. Take them as either entertaining or cringe-inducing war stories. ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 8
slide-9
SLIDE 9
  • I. Blunt Code
The first category of dirty tricks relates to writing code. ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 9
slide-10
SLIDE 10 The Code Crowbar This trick relates to adding unit tests to diffjcult-to-test legacy code. http://www.flickr.com/photos/toasty/4903485751 ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 10
slide-11
SLIDE 11 class WidgetTest { public: void TestPizazz() { Widget w; w.vim = 2; w.vigor = 5; assert(w.Pizazz() == 10); } }; Imagine we’d like to write this test for a Widget class. ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 11
slide-12
SLIDE 12 class Widget { public: // ... private: int vim; int vigor; int Pizazz() { return vim * vigor; } }; But we can’t, because the data and method we’d like to test are private members. ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 12
slide-13
SLIDE 13 #define private public Eventually, we need to move that stufg to a separate class. But we want working tests before we rearrange. So, we could do this before we include widget.h in our tests. ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 13
slide-14
SLIDE 14 #define private public // ... or ... friend class WidgetTest; That’s horrible and ugly, right? Breaking open the Widget class (temporarily) is slightly less evil. ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 14
slide-15
SLIDE 15 class WidgetConfig { public: WidgetConfig(int vim, int vigor) : vim(vim), vigor(vigor) {} int Pizazz() { return vim * vigor; } private: int vim; int vigor; }; Once the tests pass, we can safely move the configuration to its own more testable class... ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 15
slide-16
SLIDE 16 class Widget { public: // ... private: WidgetConfig config; }; ...and out of the Widget class. ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 16
slide-17
SLIDE 17 class WidgetConfigTest { public: void TestPizazz() { WidgetConfig wc(2, 5); assert(wc.Pizazz() == 10); } }; Our test now compiles and runs without any shenanigans. ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 17
slide-18
SLIDE 18 #macro ABUSE Next up: macro abuse. I’m as suspicious of macro-heavy code as the next developer. For entertainment sometime, try looking up “macro abuse” on Stack Overflow. ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 18
slide-19
SLIDE 19 /* * Your horror stories? */ #define TRUE 0 We won’t be talking about examples this egregious. ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 19
slide-20
SLIDE 20 someComplicatedFunction( LONG_NAME_FOR_FOO, WITH_FOO_AND_BAR, BAR_VALUE); someComplicatedFunction( LONG_NAME_FOR_QUUX, WITH_QUUX_AND_BAZ, BAR_VALUE); Let’s look instead at a legitimate (if stilted) use of C macros. Do you see the line of code here that isn’t like the others? ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 20
slide-21
SLIDE 21 someComplicatedFunction( LONG_NAME_FOR_FOO, WITH_FOO_AND_BAR, BAR_VALUE); someComplicatedFunction( LONG_NAME_FOR_QUUX, WITH_QUUX_AND_BAZ, BAR_VALUE); Without knowing anything about these functions, we might guess that the last line should say BAZ_VALUE instead. ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 21
slide-22
SLIDE 22 #define DO_SOMETHING_WITH(k, v) {\ someComplicatedFunction(LONG_NAME_FOR_ ## k, \ WITH_ ## k ## _AND_ ## v, \ v ## _VALUE); \ } If we were to write an ugly C macro,... ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 22
slide-23
SLIDE 23 DO_SOMETHING_WITH(FOO, BAR); DO_SOMETHING_WITH(QUUX, BAZ); ...then our intent would be much clearer in the code, and the particular error from earlier would be diffjcult to make. ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 23
slide-24
SLIDE 24 Testing? Testing! A related (ab-)use of macros is walling ofg code for testing purposes. http://www.flickr.com/photos/av_hire_london/5579137689 ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 24
slide-25
SLIDE 25 if (systemBatteryLevel() < LOW_BATTERY_THRESHOLD) { puts("Low battery"); } This function depends on a hardware-specific function. If our only use of it is for logging purposes,... ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 25
slide-26
SLIDE 26 #ifndef TESTING if (systemBatteryLevel() < LOW_BATTERY_THRESHOLD) { puts("Low battery"); } #endif ...we can wall it ofg when we’re compiling our test. This technique isn’t useful if the behavior we’re walling ofg is actually part of the function’s contract (as we’ll see later). ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 26
slide-27
SLIDE 27 Static assertions As long as we’re being too cute with C, let’s take a look at some more compile-time chicanery. http://www.flickr.com/photos/pagedooley/2128892824 ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 27
slide-28
SLIDE 28 #define MAX_SALESPEOPLE 500 int someStatistic = 30000 / (1000 - numSalespeople); Imagine a program whose statistics-gathering phase will fall over for large inputs. For now, we’re safe—the input will never be large enough to break the algorithm. ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 28
slide-29
SLIDE 29 #define MAX_SALESPEOPLE 1000 int someStatistic = 30000 / (1000 - numSalespeople); But if a later developer comes along and raises the max input size (perhaps in a feature race with the competition), the statistics code may break at runtime. ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 29
slide-30
SLIDE 30 STATIC_ASSERT(MAX_SALESPEOPLE < 1000) We could use the assert() macro to catch the problem at runtime. But the compiler can actually check some of these kinds of constraints. ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 30
slide-31
SLIDE 31 // http://www.jaggersoft.com/pubs/CVu11_3.html // #define STATIC_ASSERT(condition) \ switch(condition) { case 0: case condition: break; } There are multiple ways to implement compile-time assertions, even without the Boost
  • library. Here’s one technique from Jon Jagger.
____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 31
slide-32
SLIDE 32 The wheel, reinvented I’d rather do almost anything than roll my own TCP stack or PNG image processor for work. (For fun on the weekend is another story.) On the other hand, if the task is narrow and the risk low (e.g., test frameworks), reinventing the wheel is sometimes okay. http:// www.flickr.com/photos/29225114@N08/3094190643 ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 32
slide-33
SLIDE 33
  • II. Test Practices
The next few dirty tricks have to do with code-level testing done by the developer. ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 33
slide-34
SLIDE 34 The Stub-marine The first trick in this category is stubbing out functions. ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 34
slide-35
SLIDE 35 #ifndef TESTING if (systemBatteryLevel() < LOW_BATTERY_THRESHOLD) { puts("Low battery"); } #endif In our earlier example, we used the blunt instrument of macros to snip out hardware dependencies during testing. ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 35
slide-36
SLIDE 36 #ifndef TESTING if (systemBatteryLevel() < LOW_BATTERY_THRESHOLD) { TurnWarningLightOn(); } #endif But what if this function did something we actually needed to check during testing? ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 36
slide-37
SLIDE 37 if (batteryLevelFunc && (*batteryLevelFunc)() < LOW_BATTERY_THRESHOLD) { TurnWarningLightOn(); } In that case, we can’t just skip over that code during testing. Instead, we might use a function pointer or inheritance to let us rewire the hardware-dependent code while the test runs. ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 37
slide-38
SLIDE 38 double fakeLowBatteryLevel() { return LOW_BATTERY_THRESHOLD / 2.0; } void testAimWithLowBattery() { MindControlLaser l; l.batteryLevelFunc = &fakeLowBatteryLevel; l.Aim(); assert(l.WarningLightOn()); } Here’s a fake function that simulates a low-battery condition, and a test that uses it. ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 38
slide-39
SLIDE 39 I♥⌘C Copy-and-paste coding is one of the things I hate most in this world. And yet... ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 39
slide-40
SLIDE 40 describe Bucket do context 'when full' do subject { Bucket.new } before { subject.fill 10.blocks } {:capacity => 0, :weight => 20}.each do |name, value| its(name) { should == value } end end end ...sometimes the cure is worse than the disease. This Ruby code contains two test assertions, but they’re hidden by the torturous loop we used to try to avoid repetition. ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 40
slide-41
SLIDE 41 describe Bucket do context 'when full' do subject { Bucket.new } before { subject.fill 10.blocks } its(:capacity) { should == 0.blocks } its(:weight) { should == 20.pounds } end end If we’d just cut, pasted, and modified the assertions, we’d have much clearer test code. See David Chelimsky’s writing for more discussion on repetition vs. legibility. One other area where cut and paste can result in less confusion and better functionality: makefiles. ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 41
slide-42
SLIDE 42 Wranings and Erors [sic] Telling your compiler to report all warnings as errors can feel like a dirty trick—especially to your teammates. But in the context of this particular project, doing so resulted in many caught errors and almost no false positives. ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 42
slide-43
SLIDE 43 man’·u·al·ize v.t. To make manual. Here, I’m using “manualization” to mean “making an automated process manual.” Frequent integration and testing doesn’t have to happen on a server. Teams who constantly merge one another’s changes throughout the day are doing a form of manual CI. wiktionary.com; http:// www.flickr.com/photos/philaaronson/2485460766 ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 43
slide-44
SLIDE 44 Inspiration from elsewhere There have been books on refactoring C++ for years, but the topic didn’t really click with me until I saw it in a difgerent environment. What programming communities do you look to for inspiration? (Picture from informit.com) ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 44
slide-45
SLIDE 45
  • III. Social Beings
The last category deals with how we relate to our jobs and our teammates. ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 45
slide-46
SLIDE 46

Yes, offjcial company templates are there for a reason. But breaking them happens for a reason, too. Sometimes, the right thing to do is write your documentation in whatever format stays out of your way, then port it to the offjcial format later. http://www.flickr.com/photos/ facilitybikeclub/3197419294 ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 46
slide-47
SLIDE 47 Playing hooky Our companies pay us not just for what’s in the job description, but for the lifetime of creativity, expertise, and experience that led to our coming here. Playing hooky and coming to conferences can make us better at what we do. http://www.flickr.com/photos/reinis/ 3454438258 ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 47
slide-48
SLIDE 48 The Heist Sometimes you need a laptop with a particular Linux distro for a couple of weeks of testing,
  • r a Mac with a specific Photoshop version to decode a client’s files. Sometimes we need to
get scrappy with our resource allocation. Just be above board about whatever you do. http:// www.flickr.com/photos/rmgimages/4882451072 ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 48
slide-49
SLIDE 49 Job transformers I’d go crazy if I had to do nothing but write embedded C all day. If instead I think of my job as helping engineers make electrical measurements, that transforms my job into a programmer + document writer + tester + support technician. So much more variety! http:// www.flickr.com/photos/62109962@N07/6142290405 ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 49
slide-50
SLIDE 50 Hopes My hope is that hearing these tales has reminded you of a few groan-worthy war stories of your own, and therefore kept you entertained for the last few minutes. I also hope the talk has been a reminder that every practice has a context. I’ve enjoyed talking to and learning from you over the past two days—cheers! ____________________________________________________________________________________________________________________ Excerpt from PNSQC 2011 Copies may not be made or distributed for commercial use PNSQC.ORG 50