<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Gregory Paciga</title>
    <description>The latest articles on Forem by Gregory Paciga (@gpaciga).</description>
    <link>https://forem.com/gpaciga</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F303803%2Fb1db55c6-212e-4cb8-8bfe-bb57ac49b826.jpg</url>
      <title>Forem: Gregory Paciga</title>
      <link>https://forem.com/gpaciga</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/gpaciga"/>
    <language>en</language>
    <item>
      <title>The myth of “unstable” code</title>
      <dc:creator>Gregory Paciga</dc:creator>
      <pubDate>Tue, 13 Feb 2024 15:00:00 +0000</pubDate>
      <link>https://forem.com/gpaciga/the-myth-of-unstable-code-31of</link>
      <guid>https://forem.com/gpaciga/the-myth-of-unstable-code-31of</guid>
      <description>&lt;p&gt;The most common reason I get for people delaying test automation is that the code is “unstable”, and automating too soon will result in a lot of re-work of automation. Better to only automate after a feature is “stable”, i.e. development work is all done, they say, so you won’t have to rework any of the automation. This belief is a myth that makes automation harder in the long run, not easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your code is not unstable
&lt;/h2&gt;

&lt;p&gt;This might feel like quibbling with semantics, but consider these two statements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Our code is unstable&lt;/li&gt;
&lt;li&gt;Developers are changing the code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When I probe what people mean by “unstable”, they often consider these two statements to be the same. To me, they could not be more different. “Unstable” to me means unpredictable, that it exhibits different behaviour at different times, that there are unknown variables at play, that it is unknowable.&lt;/p&gt;

&lt;p&gt;This description should, hopefully, bear little resemblance to how your developers change code. There can be a period when developers have to experiment with how to implement something and things truly changing quite a lot, but in 90% of development work developers are working against specific requirements, acceptance criteria, and planning. You, as a QA, should be a part of those planning discussions. If you are so disconnected from the changes the developers are making that it makes the code feel “unstable”, then you have a teamwork problem, not a software problem.&lt;/p&gt;

&lt;p&gt;If your code truly is “unstable” in the sense that it doesn’t behave deterministically, then that’s a product issue. Either it’s deliberate and you need to figure out how to test for that, or it’s not deliberate and it’s a problem that needs to be fixed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your code will never be “stable”
&lt;/h2&gt;

&lt;p&gt;Let’s say we really do mean that we want to wait for the developers to be finished before doing automation. What does it mean for developers to be finished?&lt;/p&gt;

&lt;p&gt;In a waterfall or project development model, where there is a limited scope and a well defined beginning and end to the project, you might be able to do this. There are other reasons why you shouldn’t want to (which I’ll touch on below), but it could work if you can get a real commitment that development stops and you’ll have a long enough “test implementation” phase where you can automate.&lt;/p&gt;

&lt;p&gt;In product development, though, where you have a continuous backlog of work that the team moves through with incremental releases, this is impossible. If you wait until devs are done one set of features to write test automation, that set of features might be stable but the code as a whole will still be unstable because the devs are still changing it for the next set of features. Again, you might be able to work this way if you have good controls to keep separate environments for each version of the application.&lt;/p&gt;

&lt;p&gt;With ongoing product work, the product is never finished, so it will never be “stable”. This no longer works for a reason to delay automation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Waiting doesn’t prevent re-work
&lt;/h2&gt;

&lt;p&gt;The third part of this myth claims that by waiting to automate, you will prevent re-work.&lt;/p&gt;

&lt;p&gt;Again, this depends on the same fallacy: the only way automation will never require re-work is if nothing about the application ever changes. For well defined standalone projects, maybe this can be true. But I’ve yet to experience that.&lt;/p&gt;

&lt;p&gt;The re-work required for automation is actually &lt;em&gt;worse&lt;/em&gt; when you delay it based on an unattainable standard of “stability”. As I’ve written before, &lt;a href="https://gerg.dev/2024/01/three-ways-that-manual-testing-is-a-waste/"&gt;waiting to automate triples the amount of extra effort required&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Debunking the myth
&lt;/h2&gt;

&lt;p&gt;To summarize, given the mistaken belief that “we have to wait to automate because the code is unstable and we want to avoid re-work”, consider instead:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Your code isn’t unpredictable or unknowable: it is being changed deliberately by other developers on your team. Work with them so that you know what changes are coming and can plan for them.&lt;/li&gt;
&lt;li&gt;Your code is likely never going to be “stable” because software development is usually an ongoing exercise in maintaining and extending products. In most cases, if you wait for your code to stop changing, you will be waiting forever.&lt;/li&gt;
&lt;li&gt;Re-working automation is unavoidable and only gets more expensive the longer you delay keeping your automation up to date. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In limited circumstances, such as an early POC that will be thrown away before going to production or a waterfall-style standalone project, waiting to automate may make sense. In most cases, however, you will be able to have a much bigger impact on the quality of your product by automating early.&lt;/p&gt;

</description>
      <category>automation</category>
      <category>culture</category>
      <category>generaltesting</category>
    </item>
    <item>
      <title>Three ways that “Manual Testing” is a waste*</title>
      <dc:creator>Gregory Paciga</dc:creator>
      <pubDate>Tue, 23 Jan 2024 16:00:00 +0000</pubDate>
      <link>https://forem.com/gpaciga/three-ways-that-manual-testing-is-a-waste-15c2</link>
      <guid>https://forem.com/gpaciga/three-ways-that-manual-testing-is-a-waste-15c2</guid>
      <description>&lt;p&gt;* when done at the wrong time, and depending on how you define “manual testing”.&lt;/p&gt;

&lt;p&gt;Callum Akehurst-Ryan had a post recently that broke down &lt;a href="https://cakehurstryan.com/2023/09/26/is-manual-testing-a-dirty-word/https://cakehurstryan.com/2023/09/26/is-manual-testing-a-dirty-word/"&gt;much better ways of thinking about manual testing&lt;/a&gt;, but I’m using it here how it’s used at my current company and presumably many others: scripted tests that have to be run manually to see that they pass before a feature can be considered done. But that’s not the whole context: let’s first consider how manual and automated testing relate to each other.&lt;/p&gt;

&lt;h2&gt;
  
  
  Context: models for when automation happens
&lt;/h2&gt;

&lt;p&gt;I noticed last year when conducting dozens of interviews for test automation specialists (we call them “QA Engineers”, you might call them SDETs), people seemed to fall pretty cleanly into one of two camps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You have to manually test something first so that you know it works before you can automate it. Typically, people in this camp will only tackle test automation after a feature is done and “stable”, which usually means that the tests are automated one sprint after after development and manual testing are done. &lt;/li&gt;
&lt;li&gt;Automation (and indeed, testing as a whole) should be treated as part of development itself, so a feature can not be considered done until the automated tests for it are implemented.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Colloquially people refer to these as “N+1 automation” or “In-sprint automation”, respectively. It is certainly possible that the first mode all takes place within one sprint, but it’s usually unrealistic to simply condense the timeline that much. (People against “in-sprint” often mistakenly think that is the only difference and therefore throw it out as impossible for just that reason.) The difference really comes in the order things occur:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--L5XcfN_C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i0.wp.com/gerg.dev/wp-content/uploads/2024/01/n-plus-one.png%3Fresize%3D866%252C113%26ssl%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--L5XcfN_C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i0.wp.com/gerg.dev/wp-content/uploads/2024/01/n-plus-one.png%3Fresize%3D866%252C113%26ssl%3D1" alt="" width="800" height="104"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;N+1 automation: a feature is considered done after all manual tests pass, and now automated tests can be implemented without fear that the feature will change. Usually, this is done in a new sprint.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nkozfjxr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i0.wp.com/gerg.dev/wp-content/uploads/2024/01/in-sprint.png%3Fresize%3D866%252C113%26ssl%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nkozfjxr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i0.wp.com/gerg.dev/wp-content/uploads/2024/01/in-sprint.png%3Fresize%3D866%252C113%26ssl%3D1" alt="" width="800" height="104"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;In-sprint automation: manual tests cover what automation can’t, and the feature isn’t considered done until both are complete. The steps don’t have to happen serially as shown, as long as all three are part of the definition of done.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The reason that the second model looks to some like doing 2 sprints worth of work in 1 is that &lt;strong&gt;&lt;em&gt;N+1 automation is inherently wasteful&lt;/em&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Three wastes of manually testing before automating
&lt;/h2&gt;

&lt;p&gt;(You’re now free to drag me in the comments for putting the onus of waste entirely on manually testing in the post title.)&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The automated tests will always be out of date
&lt;/h3&gt;

&lt;p&gt;Consider what happens when all manual tests pass, so the feature is marked done and deployed one afternoon. That night, your automated test runs against this new code. On Thursday morning when you come in to review the results, what do you find?&lt;/p&gt;

&lt;p&gt;Any automated tests that depended on the way your code behaved before this new change will have failed. Your tests are out of date. Can you rely on the results of your tests to tell you anything about the health of the system now? Are you sure that the tests that passed &lt;em&gt;should&lt;/em&gt; have passed with the new code? These automated tests aren’t any good for regression anymore. They may be better than nothing, but it’s a lot harder to interpret.&lt;/p&gt;

&lt;p&gt;Since it may take a sprint of work to update all those tests based on a sprint’s worth of dev work, you can expect your tests to be broken for a full sprint on average. Then, of course, the cycle repeats because in that time a new batch of dev work is done.&lt;/p&gt;

&lt;p&gt;Congratulations, you’re now spending the rest of your life updating “broken” tests and will never expect to see your automated test suite pass in full again. I’m not exaggerating here — I’ve talked to people who literally expect 20-50% of their test suite to be failing at all times.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. You’re doing something manually that could have been automated
&lt;/h3&gt;

&lt;p&gt;Since you’re comfortable with calling the feature done after manually testing it, you must have manually tested every scenario that was important to you. These are likely going to be the first things that are worth automating, so you don’t have to manually test them again. But then, why didn’t you just automate it in the first place? If you claim that writing and running a manual test is faster than automating it (a dubious claim to begin with), how many times did you repeat that manual test during the development sprint when something changed? How much extra overhead is it going to be to figure out which manual tests have to be repeated after automation is in place and which don’t?&lt;/p&gt;

&lt;p&gt;You’re testing something with automation that you already tested manually. You’re wasting time testing it again. You’ll get the benefit of being able to re-run it or include it in regressions going forward, but you’d have had that from automating it up-front as well. You’ve only just delayed that benefit by a full sprint and gotten nothing in return.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Everything is more expensive
&lt;/h3&gt;

&lt;p&gt;By the time you get around to automating a feature from last sprint, your developers have moved on to something else. When you inevitably need help, need some behaviour clarified, or even find a problem that manual tests missed, the context switch required for the rest of your team is much larger than if that story was still part of the current sprint. People have to drop work they committed to in the current sprint to remember what happened last sprint. Often the “completed” feature has already gone to production and the cost of fixing new issues has also gone way up. Something that might have taken a 5-minute back-and-forth with a developer to fix while the feature was in progress will now require a lot more effort. Easy but low-priority fixes will be dropped as a result, and your overall quality suffers.&lt;/p&gt;

&lt;p&gt;One answer to this may just be that you should have caught it while manually testing. And that may be true, but you didn’t, so now what? Automated and manual tests have different strengths and will always raise different bugs. The value you get from automation is now much lower because even if you find all the same bugs as if you had automated earlier, the cost to do anything about them is higher.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automate what should be automated
&lt;/h2&gt;

&lt;p&gt;In my experience, these forms of waste far outweigh any benefit you get from only automating “stable” features. Instead of updating and re-running automated tests when code changes, you’re performing the same manual tests multiple times. Instead of getting the confidence of a reliably passing test suite, your tests are always failing and require extra analysis time as a result. Instead of working &lt;em&gt;with&lt;/em&gt; developers and improving quality, automation becomes a drag &lt;em&gt;against&lt;/em&gt; the team’s dev productivity.&lt;/p&gt;

&lt;p&gt;By automating tests first, as part of the development work, manual test effort can focus on the sorts of tests that humans are good at. Automate 100% of the tests that should be automated, as Alan Page might say, rather than wasting time pretending that you’re a better robot than a robot is. You’ll get more value from &lt;em&gt;both&lt;/em&gt; your automated tests &lt;em&gt;and&lt;/em&gt; your manual efforts that way.&lt;/p&gt;

&lt;p&gt;If you’re worried that you won’t have eyes on every path if some are automated up-front, remember that most automation still requires stepping through the application and observing its behaviour while you write the code to execute those same interactions. A good automator will watch each new tests and &lt;a href="https://gerg.dev/2018/10/all-your-automated-tests-should-fail/"&gt;make sure they can all fail&lt;/a&gt;, thus writing automation also gives you manual—or rather, human—coverage.&lt;/p&gt;

&lt;p&gt;The change in sequence alone may not be enough to get you all the way to in-sprint automation, but you should see it as much more attainable without the extra waste holding you back.&lt;/p&gt;

</description>
      <category>automation</category>
      <category>generaltesting</category>
      <category>agile</category>
      <category>alanpage</category>
    </item>
    <item>
      <title>The Secret Skill on Your QA Resume</title>
      <dc:creator>Gregory Paciga</dc:creator>
      <pubDate>Thu, 21 Dec 2023 22:49:51 +0000</pubDate>
      <link>https://forem.com/gpaciga/the-secret-skill-on-your-qa-resume-16kb</link>
      <guid>https://forem.com/gpaciga/the-secret-skill-on-your-qa-resume-16kb</guid>
      <description>&lt;p&gt;There’s a particular skill that is on full display in your tester, QA, or quality engineer resume that you may not even realize is there: the ability to be concise.&lt;/p&gt;

&lt;p&gt;The most common resume structure I saw this year went something like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A summary section with bullets describing a person’s experience and skills&lt;/li&gt;
&lt;li&gt;A table of technical skills&lt;/li&gt;
&lt;li&gt;Job experience with each job getting another set of bullet points&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s not an exaggeration to say that each one of those components was often a full page or more. When that happened, I would notice the same details being repeated multiple times, as if one thought it would emphasize that skill more or make it more likely to get past an automatic filter. Selfishly this is a problem because it means the information density is lower: I have to read more to get the same level of detail. But ok, I can slog through that if I have to. However, in an indirect way, it can also flag problems with your approach to testing.&lt;/p&gt;

&lt;p&gt;Since there is always an infinite amount of testing we &lt;em&gt;could&lt;/em&gt; do, but a limited time to do it in, an essential skill for a tester is knowing how to avoid repeating themselves. Testing something twice doesn’t tell you anything more than testing it once. I touched on this when describing some &lt;a href="https://gerg.dev/2023/08/bad-reasons-to-test/"&gt;bad reasons to test&lt;/a&gt; and the importance of &lt;a href="https://gerg.dev/2020/09/agile-testing-book-club-do-your-tests-have-purpose/"&gt;each test having a purpose&lt;/a&gt;. It’s also a fundamental part of the testing pyramid: the top layers can be smaller because you don’t need to repeat things you’ve tested at lower levels.&lt;/p&gt;

&lt;p&gt;This is especially true in test automation, where we have to be economical with which tests we implement &lt;em&gt;and&lt;/em&gt; with how much code we write, by using good coding practices like, among others, the “don’t repeat yourself” principle. Code written twice is more than twice as much work to maintain, since there’s overhead in remembering something was done twice in the first place.&lt;/p&gt;

&lt;p&gt;Now apply this to your resume: why tell me 4 times that you’ve worked with Selenium when once will do? What value does that add?&lt;/p&gt;

&lt;p&gt;Some tips that might help keep things concise:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you use a table or sidebar to list a bunch of technology that you’re familiar with, you don’t need to repeat them again in full sentences under each job.&lt;/li&gt;
&lt;li&gt;If you’ve done something similar across many jobs, consider putting in into a summary section rather than repeating the same sentence every time. Use the space you have for each job to highlight what is different or unique about what you did while there.&lt;/li&gt;
&lt;li&gt;Don’t include many variations to describe the same work. Filler phrases like “Test Design”, “Test creation”, “Test Scenarios”, “Test Cases”, “Test Scripts”, and even “writing tests” all effectively mean the same thing (because they all mean something different at every company). Instead of stuffing your resume with all of them, include only the ones the job posting asks for. The same goes for other filler like “Defect Tracking”, “Defect Management”, “Defect Reporting”, “Defect retesting”, “Test Reports”, “Regression Testing”, “Sanity Testing”, “Smoke Testing”, “Functional Testing”, “System Testing”.&lt;/li&gt;
&lt;li&gt;Focus on what differentiates you from anybody else working in the same field. I called those phrases in the previous point “filler” because they mean very little and almost everybody has them. All things equal, I’m not going to make a hiring decision based on one resume including “regression testing” or not. Unless the job description mentions it, or you really do have a depth in one area that is worth highlighting, leave it out.&lt;/li&gt;
&lt;li&gt;Avoid needless detail. A sentence to tell me you “use locators to identify elements on the page” doesn’t add much if you’ve already mentioned working with Selenium. I’ve also seen multiple bullet points dedicated to “creating branches, pulling updates, pushing code, and merging code” in a single resume where just listing “git” as a skill says the same.&lt;/li&gt;
&lt;li&gt;For each bullet point you write, ask what information it adds. If all the information it adds is already found elsewhere in your resume, delete it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If I notice a lot of waste like this in your resume, I am going to wonder about how efficient you will be when it comes to writing either a test plan or an automated suite. Be concise.&lt;/p&gt;

&lt;p&gt;You’re now free to get in the comments to tell me how I could have made the same point in half the space.&lt;/p&gt;

</description>
      <category>career</category>
      <category>cv</category>
      <category>dontrepeatyourself</category>
      <category>jobhunting</category>
    </item>
    <item>
      <title>Bad reasons to test</title>
      <dc:creator>Gregory Paciga</dc:creator>
      <pubDate>Fri, 11 Aug 2023 01:48:57 +0000</pubDate>
      <link>https://forem.com/gpaciga/bad-reasons-to-test-3hli</link>
      <guid>https://forem.com/gpaciga/bad-reasons-to-test-3hli</guid>
      <description>&lt;p&gt;“Complete” testing is impossible, so we have to do the best we can with the time and resources we have. Often, that comes down to making sure that there’s a good reason for each test to exist. If there isn’t, then you should remove it and spend that time on something more valuable. When evaluating test suites, I will ask, “why do you have this test?” or “why are you testing this?” To me, a good reason is that the test addresses some &lt;em&gt;specific&lt;/em&gt; concern, risk, or functionality &lt;em&gt;that no other test does&lt;/em&gt;. But, I’ve heard plenty of bad reasons, too…&lt;/p&gt;

&lt;h2&gt;
  
  
  To cover all the scenarios
&lt;/h2&gt;

&lt;p&gt;Ok, but which scenario does &lt;em&gt;this&lt;/em&gt; test cover? Do you have a list of “all” the scenarios? Is each one unique? What makes them unique? Who gave you that list? Is it ever possible to cover them all if you did have such a list?&lt;/p&gt;

&lt;h2&gt;
  
  
  To get more confidence
&lt;/h2&gt;

&lt;p&gt;What are you more confident about after running this one test that you weren’t confident about before? Could you run another test to give you that same confidence? Why not? What are you worried about happening if we didn’t run this test?&lt;/p&gt;

&lt;h2&gt;
  
  
  To see that it works
&lt;/h2&gt;

&lt;p&gt;To see that &lt;em&gt;what&lt;/em&gt; works? It can’t be the product or application, because that’s what all the tests do. What could be broken if we didn’t run this test?&lt;/p&gt;

&lt;h2&gt;
  
  
  Because the Product Owner told us to
&lt;/h2&gt;

&lt;p&gt;What does the Product Owner know that you don’t? Do they have a reason? You should probably know what it is too. Maybe there’s a more effective way to test that aspect, but you have to know what aspect they’re interested in first. If they don’t have a reason, it’s probably part of your job to steer them towards more useful tests and, perhaps, illustrating why this one isn’t necessary.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I care
&lt;/h2&gt;

&lt;p&gt;If you don’t know what a test tests, how are you going to interpret it when it fails? Tests are only valuable if they tell us something useful when they fail. Each test costs us in time to design, write, run, analyze, and maintain. The only way to know that we’re making the most of the time and resources we have is to be sure that each test adds &lt;em&gt;specific&lt;/em&gt; value. Without that, you’ll never really know which ones are worth including and which should be excluded.&lt;/p&gt;

</description>
      <category>automation</category>
      <category>generaltesting</category>
      <category>agiletesting</category>
      <category>cost</category>
    </item>
    <item>
      <title>You might not need to fix your flakey tests</title>
      <dc:creator>Gregory Paciga</dc:creator>
      <pubDate>Tue, 08 Mar 2022 15:00:00 +0000</pubDate>
      <link>https://forem.com/gpaciga/you-might-not-need-to-fix-your-flakey-tests-5e8g</link>
      <guid>https://forem.com/gpaciga/you-might-not-need-to-fix-your-flakey-tests-5e8g</guid>
      <description>&lt;p&gt;There’s a toxic cycle that can be caused by flakey tests. The more unreliable tests are, the less likely you are to trust their results. At best, it means wasted time as people re-run a failing step in an automated pipeline until they get the result they want. It then takes 2 or 3 times longer to identify when a failure is “real” compared to noticing it the first time they fail. At worst, it means the test results get ignored completely. “It’s probably fine, it always fails,” someone might say. This is often an excuse to keep tests out of automated pipelines, or leave them as non-blocking. “We can’t let failing tests get in the way of releasing, because failing tests are never real.”&lt;/p&gt;

&lt;p&gt;The feedback loop comes in because as soon as you start ignoring one flaky result, it becomes easier to ignore two or three flaky tests. The less you look at test results, the easier it is let them get even flakier. As they get even flakier, you trust them even less, and the loop repeats.&lt;/p&gt;

&lt;p&gt;There’s two obvious ways to break out of this cycle: you either have to fix the tests, or finally admit that they aren’t adding value and get rid of them.&lt;/p&gt;

&lt;p&gt;Often people take for granted that the &lt;em&gt;right&lt;/em&gt; thing to do is to fix the tests. People outside a team where this is a problem will ask “why doesn’t the team just fix the tests?” as if it’s not an idea they considered. Maybe it’s a matter of time, competing priorities, or expertise. Maybe someone just has to insist on making the tests blocking and accept that they can’t release until they’re made reliable. But that’s the obvious route to go because we default to believing that tests are good, and more tests are better.&lt;/p&gt;

&lt;p&gt;The rarer question, it seems, is: “are these tests actually useful?” It could very well be true that the one flakey test is also the only one that actually catches real bugs. This is always the excuse to default to keeping every test: “No I can’t remember the last time this caught a real bug, but what if one day we &lt;em&gt;did&lt;/em&gt; introduce a bug here?” However, when we find ourselves so deep in the toxic feedback loop that people barely even notice when the tests fail, it’s very likely that people wouldn’t notice if those tests ever did catch a real bug anyway. &lt;em&gt;Especially&lt;/em&gt; if it’s an intermittent bug. (And sometimes, a flaky tests is flakey because the app is flakey, but tests get the blame).&lt;/p&gt;

&lt;p&gt;How do you know when it really is safe to cut your losses and delete the flakey test? One way to think of it is to remember what tests are actually for. We don’t have tests just to see them passing or failing; on one level at least, we test in order to catch issues before they make it to production. So, are the flakey tests helping that goal, or hindering it?&lt;/p&gt;

&lt;p&gt;I recently spoke with a group with this exact problem: automated testing wasn’t being included in their release pipelines because it was too flakey, and it was hard to put effort into fixing flakey tests because they were too easily ignored outside the pipeline. But here’s where context matters: their change fail rate was consistently well under 10%. Products had 2 or 3 production issues per year, and each was usually addressed in a few hours. For this group, that was quite good. Nobody on the team was stressed by it and their stakeholders were happy. And this was &lt;em&gt;in spite&lt;/em&gt; of the fact that big pieces of automated testing were frequently ignored.&lt;/p&gt;

&lt;p&gt;While there is always a risk that dropping tests will allow more issues going unnoticed until it’s too late, in this scenario that isn’t going to be as much of a concern. If it’s true that tests &lt;em&gt;already&lt;/em&gt; weren’t doing their job with no ill effects in production, then there was little point running them in the first place, and &lt;em&gt;even less&lt;/em&gt; point in investing time to fix them. Their process was already safe enough without them.&lt;/p&gt;

&lt;p&gt;Context here matters more than anything else, but just maybe you don’t need to bother fixing those flakey tests after all. Would anybody notice if you just deleted them instead?&lt;/p&gt;

</description>
      <category>automation</category>
      <category>changefailrate</category>
      <category>flakeytests</category>
      <category>flakytests</category>
    </item>
    <item>
      <title>Coffee break tests: An exercise in test design</title>
      <dc:creator>Gregory Paciga</dc:creator>
      <pubDate>Tue, 01 Mar 2022 03:00:00 +0000</pubDate>
      <link>https://forem.com/gpaciga/coffee-break-tests-an-exercise-in-test-design-25a4</link>
      <guid>https://forem.com/gpaciga/coffee-break-tests-an-exercise-in-test-design-25a4</guid>
      <description>&lt;p&gt;Let’s think about an example test scenario.&lt;/p&gt;

&lt;p&gt;We’re given a program called MoverBot that is responsible for distributing a data file created by another program, OutputBot, to several servers. Since the two programs operate asynchronously with variable runtimes, OutputBot and MoverBot communicate about which files are ready to be distributed through a shared database entry. OutputBot adds the new file to the database when it is ready to be distributed, and MoverBot marks when that file is done.&lt;/p&gt;

&lt;p&gt;The “happy path” might be written like so:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Given&lt;/em&gt;&lt;/strong&gt; a file to be distributed &lt;strong&gt;&lt;em&gt;and&lt;/em&gt;&lt;/strong&gt; an entry in the database,&lt;br&gt;&lt;br&gt;
_ &lt;strong&gt;When&lt;/strong&gt; _ MoverBot runs,&lt;br&gt;&lt;br&gt;
&lt;strong&gt;&lt;em&gt;Then&lt;/em&gt;&lt;/strong&gt; the file is copied to each server.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, we should also consider the case where MoverBot shouldn’t distribute the file:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Given&lt;/em&gt;&lt;/strong&gt; a file to be distributed &lt;strong&gt;&lt;em&gt;and&lt;/em&gt;&lt;/strong&gt; there is not an entry in the database,&lt;br&gt;&lt;br&gt;
&lt;strong&gt;&lt;em&gt;When&lt;/em&gt;&lt;/strong&gt; MoverBot runs,&lt;br&gt;&lt;br&gt;
&lt;strong&gt;&lt;em&gt;Then&lt;/em&gt;&lt;/strong&gt; the file is not copied to any server.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Can you spot the problem with that test?&lt;/p&gt;

&lt;p&gt;Early in my testing career I included an equivalent test in a test plan for something a lot like MoverBot, but luckily it didn’t survive peer review. The problem is that instead of running the test, you could go for a coffee break and come back to the same result. Like so:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Given&lt;/em&gt;&lt;/strong&gt; a file to be distributed &lt;strong&gt;&lt;em&gt;and&lt;/em&gt;&lt;/strong&gt; there is not an entry in the database,&lt;br&gt;&lt;br&gt;
&lt;strong&gt;&lt;em&gt;When&lt;/em&gt;&lt;/strong&gt; I go for a coffee break and come back without running anything,&lt;br&gt;&lt;br&gt;
&lt;strong&gt;&lt;em&gt;Then&lt;/em&gt;&lt;/strong&gt; the file is not copied to any server.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In other words: given any scenario at all, when I do nothing, nothing happens.&lt;/p&gt;

&lt;p&gt;To improve this, we need to ask: what bug (or risk) is this test trying to catch (or mitigate)? Once we answer that, we can do a better job of designing the test. These “negative tests”, if you want to call them that, aren’t just for exercising some behaviour. They need to demonstrate that some erroneous behaviour doesn’t exist.&lt;/p&gt;

&lt;p&gt;In this case, what I wanted to do was show that the database entry actually does control whether the file is distributed or not. I needed a control to show that MoverBot &lt;em&gt;would&lt;/em&gt; have distributed the file without the database entry given a chance. In other words, I needed to show that MoverBot was perfectly capable of distributing files, it just opted not to for this case. This is the revised test:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Given&lt;/em&gt;&lt;/strong&gt; two files to be distributed &lt;strong&gt;&lt;em&gt;and&lt;/em&gt;&lt;/strong&gt; only one has an entry in the database,&lt;br&gt;&lt;br&gt;
&lt;strong&gt;&lt;em&gt;When&lt;/em&gt;&lt;/strong&gt; MoverBot runs,&lt;br&gt;&lt;br&gt;
&lt;strong&gt;&lt;em&gt;Then&lt;/em&gt;&lt;/strong&gt; only the file with the database entry is copied to any server.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We know now that if MoverBot wasn’t reading the database entry correctly it probably would have happily distributed both files. Since it only distributed one file, it must be respecting the database entry.&lt;/p&gt;

&lt;p&gt;This particular example is equivalent to running both the first “happy case” and the “coffee break test” at the same time. One might argue that given the happy case is there and presumably passes, you don’t need the control in the negative test. However, that is only true if both tests always run together and you can guarantee there are no bugs in how the second test is set up. Remember, automated tests are code, and all code can have bugs!&lt;/p&gt;

&lt;p&gt;Including controls directly in your tests are a way of proving, in a self-contained way, that the test setup is correct, and that you would have seen the bug manifested if it existed. They let you say with confidence that the only reason nothing happened is because nothing was supposed to happen. They aren’t always necessary, but if going for a coffee break would give you the same result otherwise, it’s a smart move to include them.&lt;/p&gt;

</description>
      <category>automation</category>
      <category>controls</category>
      <category>design</category>
      <category>negativetests</category>
    </item>
    <item>
      <title>Testing in 2021, according to my Twitter bookmarks</title>
      <dc:creator>Gregory Paciga</dc:creator>
      <pubDate>Tue, 11 Jan 2022 15:00:00 +0000</pubDate>
      <link>https://forem.com/gpaciga/testing-in-2021-according-to-my-twitter-bookmarks-3k2p</link>
      <guid>https://forem.com/gpaciga/testing-in-2021-according-to-my-twitter-bookmarks-3k2p</guid>
      <description>&lt;p&gt;My annual roundup of all the things about testing (and working as a programmer more generally) on Twitter that I found interesting enough to bookmark.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“&lt;a href="https://twitter.com/sindokolenchery/status/1346294901965639680?s=20"&gt;A picture is worth a thousand assertions&lt;/a&gt;“, quoting Angie Jones from the &lt;a href="https://testandcode.com/141"&gt;Test And Code podcast&lt;/a&gt; (but remember that all those assertions happen at once without being itemized)&lt;/li&gt;
&lt;li&gt;Angie Jones also helped break down &lt;a href="https://applitools.com/blog/selenium-vs-cypress-the-rematch/?utm_campaign=%5BBlog%5D-Selenium-vs-Cypress:-The-Rematch&amp;amp;utm_medium=Organic-Social&amp;amp;utm_source=Twitter&amp;amp;utm_term=CAT&amp;amp;utm_content=Blog"&gt;the last two years of development in WebDriver and Cypress&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;John Cutler identified&lt;a href="https://twitter.com/johncutlefish/status/1346542915439345664?s=20"&gt;an overlap between observability and product analytics&lt;/a&gt;, which also works for testing.&lt;/li&gt;
&lt;li&gt;Ben Sigelman pointed out &lt;a href="https://twitter.com/el_bhs/status/1349406398388400128?s=20"&gt;the difference between observability and monitoring&lt;/a&gt;, and how the compliment each other.&lt;/li&gt;
&lt;li&gt;Some &lt;a href="https://www.freecodecamp.org/news/what-google-taught-me-about-code-reviews/"&gt;tips from Google on doing code reviews&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://twitter.com/dev_nikema"&gt;This thread started by Nikema Prophet&lt;/a&gt; has a lot of &lt;a href="https://twitter.com/dev_nikema/status/1350233517137907713"&gt;great books recommendations on writing code&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Trish Khoo called the idea that testers have a mindset different from developers “&lt;a href="https://twitter.com/hogfish/status/1351692222421377025?s=20"&gt;one of the dumbest myths I’ve ever heard&lt;/a&gt;“, eleven months before &lt;a href="https://gerg.dev/2021/12/gatekeeping-in-testing/"&gt;I also wrote about it&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;This quote from W. Edwards Deming struck me as important for my work in metrics, and is still something I need to dig into more: “&lt;a href="https://twitter.com/johncutlefish/status/1352827946386382850?s=20"&gt;It is wrong to suppose that you can’t measure it, you can’t manage it&lt;/a&gt;“&lt;/li&gt;
&lt;li&gt;Speaking of metrics, Theresa Neate raised an interesting question: &lt;a href="https://twitter.com/TheresaNeate/status/1424316848359690247?s=20"&gt;what are “vanity” testing metrics vs actually meaningful metrics?&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;I didn’t get a chance to participate myself, but I loved this idea from Ministry of Testing to run &lt;a href="https://twitter.com/ministryoftest/status/1356183518737522695"&gt;test automation challenges&lt;/a&gt; and have us compare solutions.&lt;/li&gt;
&lt;li&gt;Amy Tobey suggested &lt;a href="https://twitter.com/MissAmyTobey/status/1367894771339907073"&gt;renaming “machine learning” to “automated bias”&lt;/a&gt; and I am on board.&lt;/li&gt;
&lt;li&gt;Nat Alison emphasized &lt;a href="https://twitter.com/tesseralis/status/1374191166061637637?s=20"&gt;how important good documentation is for engineer productivity&lt;/a&gt;, likening it to memoization (i.e., storing the result of an expensive function call).&lt;/li&gt;
&lt;li&gt;Charity Majors shared some &lt;a href="https://twitter.com/mipsytipsy/status/1377845930490126336?s=20"&gt;awesome slides about why software should auto-deploy in 15 minutes&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;This was a great roundup of &lt;a href="https://applitools.com/blog/unpopular-opinions-software-testing-edition/?utm_campaign=%5BBlog-Post%5D-Unpopular-Opinion:-Software-Testing-Edition&amp;amp;utm_medium=Organic-Social&amp;amp;utm_source=Twitter&amp;amp;utm_term=angie-social&amp;amp;utm_content=Blog"&gt;unpopular opinions about testing&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://twitter.com/RobMcCargow/status/1381645553843499008?s=20"&gt;Rob McCargow suggested&lt;/a&gt; reading “9 Rules for Humans in the Age of Automation” by Kevin Roose.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://twitter.com/b0rk/status/1382383203999219716?s=20"&gt;Julia Evans&lt;/a&gt;, known (by me at least) for &lt;a href="https://wizardzines.com/"&gt;her great zines on programming&lt;/a&gt;, put together a neat &lt;a href="https://computer-mysteries.netlify.app/slow-website.html"&gt;choose-your-own-adventure game about debugging a computer networking problem&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;We’ve all seen photos showing examples of products that look like unit tests worked but the integration tests failed. Johanna South posted a great example of the inverse: &lt;a href="https://twitter.com/theQAconnection/status/1441128181914746882"&gt;when integration passes even though unit tests failed&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;I found these &lt;a href="https://twitter.com/GeePawHill/status/1442524237470728193?s=20"&gt;tips on coaching&lt;/a&gt; helpful at a time when I was struggling to have an impact.&lt;/li&gt;
&lt;li&gt;Some &lt;a href="https://twitter.com/johncutlefish/status/1463240570990518273?s=20"&gt;&lt;em&gt;real&lt;/em&gt; perks of a good employer&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Some great &lt;a href="https://twitter.com/johncutlefish/status/1414432716242649088?s=20"&gt;prompts for articulating hypotheses and research questions&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;I can’t find an original source, but &lt;a href="https://twitter.com/i_anic/status/1465722897524269070"&gt;Prince Charles and Ozzy Osbourne showed up as a fun warning about personas&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;This is still a work in progress, but I’m very interested to see what Richard Bradshaw and Mark Winteringham will come up with for their &lt;a href="https://twitter.com/FriendlyTester/status/1478800993525673986?s=20"&gt;proposed test automation curriculum&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’m using twitter less compared to previous years, but you can still find my similar summaries from &lt;a href="https://gerg.dev/2019/12/testing-2019-on-twitter/"&gt;2019&lt;/a&gt; and &lt;a href="https://gerg.dev/2020/12/testing-in-2020-according-to-my-twitter-bookmarks/"&gt;2020&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>twitter</category>
      <category>analytics</category>
    </item>
    <item>
      <title>Gatekeeping in testing</title>
      <dc:creator>Gregory Paciga</dc:creator>
      <pubDate>Tue, 21 Dec 2021 15:00:00 +0000</pubDate>
      <link>https://forem.com/gpaciga/gatekeeping-in-testing-ijj</link>
      <guid>https://forem.com/gpaciga/gatekeeping-in-testing-ijj</guid>
      <description>&lt;p&gt;We often talking about gatekeeping in testing as a problem in the sense that testers shouldn’t be the ones that decide when something goes out to production. But “gatekeeping” can also be used in the sense of excluding others. In fan communities you might hear “you aren’t a &lt;em&gt;real&lt;/em&gt; Marvel fan if you’ve only seen the movies”. In software dev, a common example is “you aren’t a &lt;em&gt;real&lt;/em&gt; web developer if you only know vanilla Javascript” or “you aren’t a &lt;em&gt;real&lt;/em&gt; developer if your github commit history isn’t all green.”&lt;/p&gt;

&lt;p&gt;I’ve become somewhat jaded with the testing discourse online in part because I think testers, as a community, tend to be guilty of this as well, albeit less explicitly. When the idea for this post first came to mind, it wasn’t until I saw few recent viral moments on twitter about gatekeeping developers that I made the connection.&lt;/p&gt;

&lt;p&gt;Probably the most obvious example is the consistent myth that there is a “tester’s mindset” that precludes developers from being able to test their own code. This is what enables a “gatekeeper to production” role to develop in the first place, and creates bottlenecks as multiple developers funnel every ticket through limited testing people on a team.&lt;/p&gt;

&lt;p&gt;Plenty of ink has already been spilt on why this false dichotomy is detrimental. But, we do it in more subtle ways as well.&lt;/p&gt;

&lt;p&gt;Testers of all stripes, famously and annoyingly, love to debate terminology. Take the “testing vs checking” question. Some well-known testers feel very strongly that these need to be differentiated, and that it is detrimental to the craft of testing if we aren’t careful about which we use. I understand the historic contexts that led to a need for that distinction (for one, it was a reaction against “let’s just automate everything”). But never once have I seen the value of making that distinction when talking to a developer on a project. The only people who do are testers talking to other testers about testing, and failing to make that distinction can be flagged as a sign that you aren’t a &lt;em&gt;real&lt;/em&gt; tester.&lt;/p&gt;

&lt;p&gt;In that same category I would add much of tester jargon and debates: “oracles”, “heuristics”, whether a tool is a test tool or not, testing vs QA (“but you can’t &lt;em&gt;assure&lt;/em&gt; anything”, the &lt;em&gt;real&lt;/em&gt; testers say). I once saw a conference speaker refer to the work of “Jerry” (no last name) several times before someone in the crowd had to stop them and ask “who’s Jerry?” (Are you a &lt;em&gt;real&lt;/em&gt; tester if you haven’t read any &lt;a href="https://en.wikipedia.org/wiki/Gerald_Weinberg"&gt;Gerald Weinberg&lt;/a&gt;?)&lt;/p&gt;

&lt;p&gt;Again, these are subtle definitions and debates that can be interesting to testers talking to testers about testing. We run into problems, however, when we expect that every person who tests should already know, understand, or care about them. They are almost never interesting to a product team talking about testing an application.&lt;/p&gt;

&lt;p&gt;So, yes: put all of those on the list of things I no longer care about as a tester. &lt;a href="https://gerg.dev/2020/07/lumpers-and-splitters-in-testing/"&gt;I’ve written about that before&lt;/a&gt;. More importantly, put them on the list of things I don’t expect anybody else to care about either. They’re not prerequisites to being a good tester nor being able to test. Plenty of testers do good work outside the twitter-sphere and conference circuit. We should not be using these inside-baseball details as &lt;a href="http://www.ruf.rice.edu/~kemmer/Words/shibboleth"&gt;shibboleths&lt;/a&gt; to filter out the real testers and exclude those who would be allies.&lt;/p&gt;

</description>
      <category>culture</category>
      <category>terminology</category>
      <category>gatekeeping</category>
      <category>geraldweinberg</category>
    </item>
    <item>
      <title>Going deeper on “Should we automate each negative test?”</title>
      <dc:creator>Gregory Paciga</dc:creator>
      <pubDate>Tue, 02 Nov 2021 14:00:00 +0000</pubDate>
      <link>https://forem.com/gpaciga/going-deeper-on-should-we-automate-each-negative-test-2i9h</link>
      <guid>https://forem.com/gpaciga/going-deeper-on-should-we-automate-each-negative-test-2i9h</guid>
      <description>&lt;p&gt;In recent article on the Ministry of Testing site, Mark Winteringham asks: “&lt;a href="https://www.ministryoftesting.com/dojo/lessons/should-you-create-automation-for-each-negative-api-scenario"&gt;Should You Create Automation For Each Negative API Scenario?&lt;/a&gt;” In short, he answers that which scenarios you automate will depend entirely on what risks you’re trying to mitigate. While I’m on board with the idea that each test should have a reason behind it, I would have tackled the question differently, because I think there’s a more interesting question lurking beneath the surface.&lt;/p&gt;

&lt;p&gt;Let’s use the same example: an API that validates an email address by responding either with &lt;code&gt;200 OK&lt;/code&gt; or &lt;code&gt;400 Bad Request&lt;/code&gt;. In this context, a “positive” test scenario says that a valid email will return a &lt;code&gt;200 OK&lt;/code&gt; response. A negative scenario would say that an invalid email should get a &lt;code&gt;400 Bad Request&lt;/code&gt; response. Now we can break the question down.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Should you create automation for &lt;em&gt;one&lt;/em&gt; negative API scenario?&lt;/strong&gt; The answer to this is unequivocally yes, absolutely. Without at least one case of seeing that &lt;code&gt;400&lt;/code&gt; response, your API could be returning &lt;code&gt;200 OK&lt;/code&gt; for all requests regardless of their content. Along the same lines as my claim that &lt;a href="https://gerg.dev/2018/10/all-your-automated-tests-should-fail/"&gt;all tests should fail&lt;/a&gt;, one test doesn’t tell you much unless it shows a behaviour &lt;em&gt;in contrast&lt;/em&gt; to some other possible behaviour.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Should you create automation for &lt;em&gt;all&lt;/em&gt; negative API scenarios?&lt;/strong&gt; The answer to this should also obviously be “no”, for the same reason that you can’t automate all positive scenarios. There are infinitely many of them.&lt;/p&gt;

&lt;p&gt;Now, &lt;strong&gt;should you create automation for &lt;em&gt;each&lt;/em&gt; negative API scenario?&lt;/strong&gt; I’m not sure whether this is any different from the previous question, except for the fact that “each” implies (to me) being able to iterate through a finite list. This question actually can’t be answered as asked because, as Mark points out, there are infinite ways that an email could be considered invalid.&lt;/p&gt;

&lt;p&gt;The more interesting question I would pose instead is: &lt;strong&gt;&lt;em&gt;Which&lt;/em&gt; negative scenarios should we automate?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, this still depends on what risks you’re interested in, but even when addressing a single risk we can add a bit more information. It is safe to assume in this example that an invalid address getting into the system is going to have some negative effects associated with it, otherwise this validation API wouldn’t exist at all. But to address that singular idea of only admitting valid emails there are still an infinite number of ways to test it.&lt;/p&gt;

&lt;p&gt;At the risk of being too prescriptive, something we can likely do is break down the behaviour into two pieces:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Does the API return &lt;code&gt;400 Bad Request&lt;/code&gt; when the email fails validation?&lt;/li&gt;
&lt;li&gt;Does the email validation function fail for all invalid email addresses?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first question is now much simpler. Using one example of an email that we know fails validation should be sufficient to answer it. We’ve essentially reduced an infinite number of possible negative test cases into a single equivalence partition; i.e. a group of negative test cases from which any &lt;em&gt;one&lt;/em&gt; is capable of answering our question. If you like formal math-y lingo, you might call this “reducing the cardinality” or “normalizing” the set.&lt;/p&gt;

&lt;p&gt;The second question now says nothing about the API at all and we can hopefully tackle it as unit tests. This does stray a bit into greybox testing, but I’m not against that sort of thing if you aren’t.&lt;/p&gt;

&lt;p&gt;Our job isn’t done, though. This still should raise some questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Are there other ways the API could fail?&lt;/li&gt;
&lt;li&gt;Which negative scenarios should we automate at the unit level?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let’s take each in turn.&lt;/p&gt;

&lt;p&gt;For the first, even if the answer is yes, we should try the same trick of reducing many variations of errors into distinct modes or equivalence partitions. You might be interested in other boundaries as well. An empty email address, or no email field at all, are both distinct from the case of an invalid email. If there are other response codes that the API could return, like &lt;code&gt;401 Unauthorized&lt;/code&gt; or &lt;code&gt;404 Not Found&lt;/code&gt;, there’s a good chance you’ll want one case for each of those. You’re unlikely to need more than that, though, unless there are multiple distinct reasons for returning the same response. You could get deep into the intricacies like invalid JSON or changing the HTTP headers, but at that point you definitely need to ask if those are risks you’re worried about enough to put time into.&lt;/p&gt;

&lt;p&gt;Now the second question. You’ve probably already caught that this is the same as the “interesting question” we started with. We’ve just bumped it down to a lower level of testing. At least that means we’ve made each example cheaper to test, though there are still infinitely many.&lt;/p&gt;

&lt;p&gt;No matter what subset of the infinitely many invalid emails you pick to test, you should still be able to articulate why each version of “invalid” is different from each other version. Can you tie each one back to specific product-level risks? Probably not, in all practicality. At a product level, invalid is invalid. I doubt you’ll be able to get anybody to say that testing one invalid email mitigates a different risk than any other invalid email. Unfortunately, it doesn’t follow from that that you only need to test one, because it is still true that whatever method your product is using to validate email address could be flawed.&lt;/p&gt;

&lt;p&gt;Remember that ideally we are working at the unit level here, so hopefully you agree that it is fair to go into whitebox testing at this point. At worst, you might end up reading &lt;a href="https://www.rfc-editor.org/rfc/rfc5322"&gt;RFC 5322&lt;/a&gt; until you go cross-eyed trying to identify what actually makes an email valid or not. If you did, you could devise one negative example from each of the specifications in that RFC. More likely, you will find that either the product is using a much simpler definition of “valid” than the actual email specification, or it is using a 3rd party library.&lt;/p&gt;

&lt;p&gt;In the former case, your product team has to accept the risk of rejecting potentially valid addresses, but at least understanding the product’s definition of “invalid” will define a much more narrow set of test cases. Each negative test you use should map directly to your product’s definition. You could have fun coming up with valid emails (according to RFC 5322) that your product calls invalid, or vice verse—I once had to do exactly this as a way of needling our product team into improving our home-grown definition of a valid domain name, which has its own similarly complicated RFC. If your product’s definition is changed to account for those counterexamples, they are good candidates to retain in your tests. If not, it can be helpful to keep them as examples of how your spec knowingly diverges from the official spec, but make sure the test is explicit about the difference between a feature or a known bug. Future generations may look at specs like that and wonder whether there was a reason you have to accept invalid (or reject valid) emails, or if it was just a case of cutting corners in your validation. That is, they need to be able to know if it is safe to change those kinds of behaviours. (“Should you write tests for known bugs?” is a good topic for a separate discussion).&lt;/p&gt;

&lt;p&gt;In the latter case—using a third party library—then you’re likely not too interested in testing the internals of that too much. Your scope of testing is now defined by “how much do we trust (or distrust) this library?” If the answer is “not at all”, then you’re back to the RFC and trying to violate each example in turn. If the answer is “completely!” then you likely don’t need any more than a few broad examples (as long as they are all different from each other). One technique that sometimes works is to come up with the most outrageous input possible so you can say “if it knows this is valid, it probably understands much more normal input too”. The trick is being deliberate about your choice of “outrageous”.&lt;/p&gt;

&lt;p&gt;Finally, if you’re one of the unfortunate people who doesn’t have the option of moving scenarios down into unit tests, you’ll still have to answer these same question at the API level anyway. My advice would still be to have one test as the canonical answer to “does an invalid email get rejected”, and have a separate group of tests that are explicitly labelled as testing what it means to be an “invalid email”. Then the reason for having each set is, at least, explicit. You can still test changes to the definition of “valid” separately from changing the API’s reaction to it.&lt;/p&gt;

&lt;p&gt;I recognize that getting into the weeds of email’s RFC specifications is not likely what Mark intended with this specific example, but I think the lessons here still carry over to other features that don’t have public standards behind them. You can’t test &lt;em&gt;each&lt;/em&gt; negative test case. You &lt;em&gt;can&lt;/em&gt; limit the scope of what “negative” means based on the level of testing you’re in. You &lt;em&gt;can&lt;/em&gt; keep testing at higher levels simple by building on the tests at lower levels. And, you &lt;em&gt;can&lt;/em&gt; reduce infinite negative examples to distinct classes to test one example of each.&lt;/p&gt;

&lt;p&gt;(Re-reading this later, I realize there might also be some subtle terminology things that change the question: what is the difference between a “test”, a “test case”, and a “scenario”, for example? I know testers love bickering about terminology but I tend to &lt;a href="https://gerg.dev/2020/07/lumpers-and-splitters-in-testing/"&gt;lump things together&lt;/a&gt;. If your preferred definitions would change the above, feel free to mentally substitute in whichever words you think I’m actually talking about.)&lt;/p&gt;

</description>
      <category>automation</category>
      <category>apitesting</category>
      <category>equivalencepartition</category>
      <category>markwinteringham</category>
    </item>
    <item>
      <title>The Gambler and other fallacies in Testing</title>
      <dc:creator>Gregory Paciga</dc:creator>
      <pubDate>Tue, 26 Oct 2021 14:00:00 +0000</pubDate>
      <link>https://forem.com/gpaciga/the-gambler-and-other-fallacies-in-testing-8p1</link>
      <guid>https://forem.com/gpaciga/the-gambler-and-other-fallacies-in-testing-8p1</guid>
      <description>&lt;p&gt;I just listened to &lt;a href="https://soundcloud.com/ministryoftesting/testsphere-roulette-episode-3-david-maynard-and-emna-ayadi?in=ministryoftesting/sets/testsphere-roulette"&gt;Episode 3 of the Ministry of Testing’s TestSphere Roulette podcast series&lt;/a&gt;, and something about the conversation irked me. The discussion was centered on the Gambler’s Fallacy card, which says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The human tendency to perceive meaningful patterns within random data.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Specifically, it usually refers to a gambler playing a game of chance who might think that past results can tell him something about what is likely to come up next. In a game of roulette, after seeing a string of red, we might be tempted to think that black is “due” to come up next. Or, possibly, that red is on “a streak”, and therefore more likely to come up again on the next spin.&lt;/p&gt;

&lt;p&gt;The examples on the TestSphere card, though, describe what I think are quite different scenarios:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Creating tests for every bug as they’re found, so in a few years people wonder why there are tests for such obscure things.&lt;/li&gt;
&lt;li&gt;Repeatedly going back to test the same things that have broken in the past.&lt;/li&gt;
&lt;li&gt;A very small portion of your user base being very loud in app store reviews.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The conversation on the podcast focused on these three examples and how people had experienced them. It wasn’t until I pulled out the Gambler card myself and read through it again that I realized what bugged me. There was nothing wrong with what anybody said. The problem I have is that none of those examples on the card are examples of the Gambler’s fallacy at play, because &lt;strong&gt;&lt;em&gt;bugs aren’t random data&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I suspect a lot of us have experienced some flavour of the Pareto principle in testing. It usually goes something like this: 80% of the bugs are caused by 20% of the code. I work on a very large web app and I would say most bugs by far come from either CSS visual layout or mishandling of malformed data coming from one of the APIs. If bugs arose randomly, it would be a case of the Gambler’s fallacy to believe that past CSS bugs are a predictor of more future CSS bugs. The rational belief would be that CSS bugs should arise in proportion to how much of the app is CSS. But my experience as a tester tells me that isn’t true. In fact, there’s a different TestSphere card—the History heuristic—that reflects this: “Previous versions of your product can teach you where problematic features are or where bugs are likely to turn up.” (I’m actually surprised there’s not an orange Patterns card in TestSphere for Pareto.)&lt;/p&gt;

&lt;p&gt;This argument also applies to the user reviews example: a lot of angry reviews from a small portion of the users might be because they’re all about a significant bug that only affects that one segment of users. The Gambler’s fallacy warns that if reviews are random data, then a string of reviews from one small segment does not make the next review any more or less likely to come from that same segment. But the reverse is probably true here: a string of reviews from one small segment of your users suggests that there might be a correlation, and you should expect more reviews from that same segment in the future unless you change something.&lt;/p&gt;

&lt;p&gt;(Sidenote: The Gambler’s fallacy sometimes doesn’t even apply that well to gambling for the same reason. There’s an interesting &lt;a href="https://www.youtube.com/watch?v=ytuHV2e4c4Q"&gt;Mathologer video that walks through the math of seeing 60 red roulette spins out of 100&lt;/a&gt;. Despite what the Gambler’s fallacy might suggest, you actually should bet on red for spin 101 because it’s likely that the wheel isn’t actually random, i.e. it has a bias towards red. This is also why counting cards works.)&lt;/p&gt;

&lt;p&gt;Of course, all of this raises a question: how does the Gambler’s fallacy apply to testing? In order for the Gamer’s fallacy to really apply, we need to be looking at something with random data. And aside from a few specific cases, like where your product is actually dealing with randomness, it’s hard to see scenarios where this comes up day to day. At a stretch, we might be able to say that sufficiently rare events are &lt;em&gt;as good as&lt;/em&gt; random. For example, one request out of a billion failing in some weird unexpected mode. Even cosmic rays can cause one-off misbehaviours! An unfortunate string of cosmic bit-flips should not necessarily be taken as evidence that your product is exceptionally prone to them. This might be a case of the &lt;a href="https://en.wikipedia.org/wiki/Accident_(fallacy)"&gt;accident fallacy&lt;/a&gt;: misbehaviours are usually caused by bugs, and cosmic rays cause misbehaviours, therefore cosmic rays are bugs. But then we’re getting into a tangent about risk tolerance and probabilities.&lt;/p&gt;

&lt;p&gt;What the TestSphere card (and the podcast) was instead suggesting was that a bug occurring once shouldn’t be taken as evidence that it will occur again. I think Gambler’s fallacy is the wrong label to put on that idea, but it is worth considering on its own. I certainly agreed with the speakers on the podcast that it is important to prune our test suites, and regularly review whether the tests that it contains are valuable. However, I don’t think you can extend that to saying something as black-and-white as any assertion that tests for old bugs are unnecessary. It is difficult even to say “this bug is now impossible and thus shouldn’t be tested for”, since implementation could change to make it possible again. How likely is that? As usual, the answer is &lt;a href="https://gerg.dev/2019/02/the-most-important-and-most-useless-response-to-every-question-about-testing/"&gt;annoyingly context dependent&lt;/a&gt;. Deciding which tests are worth doing given finite time is one of the great arts of testing. Likely 90% of automated tests written will never catch a bug because it is impossible to know in advance which bugs will happen again and which won’t. But it doesn’t necessarily follow that it is good strategy to reduce your test suite by a factor of 10x. Nor does it follow that you shouldn’t add a test for a bug you’ve seen today.&lt;/p&gt;

&lt;p&gt;There can also be a belief that if a test exists, it &lt;em&gt;should&lt;/em&gt; exist. This is the &lt;a href="https://en.wikipedia.org/wiki/Is%E2%80%93ought_problem"&gt;is-ought fallacy&lt;/a&gt;. In trying to justify it, you might run afoul of the &lt;a href="https://en.wikipedia.org/wiki/Historian%27s_fallacy"&gt;Historian’s fallacy&lt;/a&gt; by thinking that if someone wrote that test in the past, they must have had a good reason for doing so, and that good reason is reason to keep it. In reality, we may have more information about our product today than the testers of the past had, so we might come to a different conclusion. I’ve also seen people use the &lt;a href="https://en.wikipedia.org/wiki/Appeal_to_tradition"&gt;Appeal to Tradition&lt;/a&gt; fallacy – “we test it that way because it’s always been tested that way”. That’s not much of a test strategy either, I dare say.&lt;/p&gt;

&lt;p&gt;At the end of the day, what I really got out of this whole discussion is that it’s great fun to read through Wikipedia’s &lt;a href="https://en.wikipedia.org/wiki/List_of_fallacies"&gt;List of Fallacies&lt;/a&gt; and think about all the ways in which they are misused in testing. Our job is often justifying what tests are worth doing, whether we think about it explicitly or not. It’s worth being able to recognize when our logic leaves something to be desired.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>fallacies</category>
    </item>
    <item>
      <title>Three ways to make metrics suck less</title>
      <dc:creator>Gregory Paciga</dc:creator>
      <pubDate>Wed, 22 Sep 2021 06:00:00 +0000</pubDate>
      <link>https://forem.com/gpaciga/three-ways-to-make-metrics-suck-less-4ac</link>
      <guid>https://forem.com/gpaciga/three-ways-to-make-metrics-suck-less-4ac</guid>
      <description>&lt;p&gt;Everybody loves to hate metrics. I get it. There are a lot of terrible metrics out there in the software development and testing world. People still propose counting commits or test cases as a measure of productivity. It’s garbage. But I also believe that measuring something can be a useful way to understand aspects of it that you couldn’t get with qualitative measures alone. I’m not going to give a defence of metrics in all cases here, but I do have a few suggestions for how to make them suck less.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Be very explicit about what a metric measures
&lt;/h2&gt;

&lt;p&gt;To take the example of counting the number of commits a developer makes. It’s a terrible metric because commits aren’t actually a measure of productivity. While the platonic ideal of a commit is that it represents a single atomic change, the amount of work involved could still involve anything from a single character change to a large refactor of a highly coupled codebase.&lt;/p&gt;

&lt;p&gt;Number of test cases run and the number of bugs found are equally bad metrics. Neither has an unambiguous way to be counted. Test cases can be broken up in all kinds of arbitrary ways to change their number. Meanwhile a single root cause might be reported as 8 different bugs across 3 application layers, either just because that’s how it manifested or because someone is incentivized to find lots of bugs.&lt;/p&gt;

&lt;p&gt;There’s a very academic but &lt;a href="http://www.kaner.com/pdfs/metrics2004.pdf"&gt;interesting paper by Kaner &amp;amp; Bond&lt;/a&gt; all about rigorously asking what metrics actually measure. They propose a series of questions to help define metrics in a way that makes sure what you’re trying to measure is explicit. In my reading, the most important aspects of it boil down to making sure you have solid answers to the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why are you measuring this? (If you don’t have a good answer, stop here.)&lt;/li&gt;
&lt;li&gt;What attribute are you actually trying to understand? (e.g., productivity)&lt;/li&gt;
&lt;li&gt;Is the metric you’re proposing actually correlated with that attribute? If the metric goes up, does that mean the attribute improved, and vice versa?&lt;/li&gt;
&lt;li&gt;What assumptions are you making about how these two things are related?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short, you want to be very explicit about why you’re looking at any particular metric, because it is very easy to track a metric that doesn’t measure what you think it does.&lt;/p&gt;

&lt;p&gt;Another important question that Kaner &amp;amp; Bond bring up is: what are the side effects of measuring this? That leads us to the next important piece.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Have a counter-metric
&lt;/h2&gt;

&lt;p&gt;One of the most common complaints about metrics is that they can always be “gamed”, or manipulated. If I start counting how many bugs people log, they’ll find ways to log more bugs. If I count commits, developers will make smaller commits. At their best, a metric will motivate positive changes, but it can always be taken too far. &lt;a href="https://en.wikipedia.org/wiki/Goodhart%27s_law"&gt;Goodhart’s law&lt;/a&gt; warns us that any metric that becomes a target immediately ceases to become a good target.&lt;/p&gt;

&lt;p&gt;If we’ve carefully thought through the side effects of making a measurement, we should know how things might go wrong. While culture plays a big role here — e.g. by making very clear that a new metric is not a measure of personal performance, actually meaning it, and having people believe you — we can be more systematic about preventing this.&lt;/p&gt;

&lt;p&gt;A classic example of counter-metrics from DevOps is that by pursuing more frequent small releases, a team might cut corners in testing. Less testing means you can release faster, but you could also see the quality of their product decrease by releasing bugs more often. This is why the “Big 4” DevOps metrics have two related to speed (release frequency and lead time) &lt;em&gt;and&lt;/em&gt; two related to stability (how many production issues there are and how long it takes to recover from them). The stability metrics are there to make sure people don’t privilege speed at all costs.&lt;/p&gt;

&lt;p&gt;(It’s also possible that doing less testing &lt;em&gt;won’t&lt;/em&gt; result in more bugs; it is possible to over-test, after all. Pairs of counter-metrics aren’t guaranteed to be anti-correlated.)&lt;/p&gt;

&lt;p&gt;It’s not always trivial to have a counter-metric. Counter-metrics are themselves metrics that will have their own side-effects. But for any metric you must ask: how will you know if it starts to do more harm than good?&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Make them temporary
&lt;/h2&gt;

&lt;p&gt;If you have a reason to measure something, there will be a reason to stop measuring it.&lt;/p&gt;

&lt;p&gt;Generally, a metric either serves as a way to observe the effects of a change, or as an early warning system.&lt;/p&gt;

&lt;p&gt;In the former case, once your goals have been met, think about getting rid of it. Make new goals and move on. Even if the goal hasn’t been met, examine why and re-evaluate. Avoid the temptation to make every metric a quota or target that has to be measured forever.&lt;/p&gt;

&lt;p&gt;Any metric related to testing usually falls into this category for me; nobody should care how many test cases ran, because at the end of the day what really matters is whether the product is able to do its job for its users. You might pay attention to counting test cases because you have a hypothesis that changing that number will improve the resulting product quality. (The “how” here matters in practice, but let’s assume for a moment that you have a legitimate reason to make the hypothesis.) There are three main possibilities:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You succeed at increasing the number of test cases run before release, and product quality improved.&lt;/li&gt;
&lt;li&gt;You succeed at increasing the number of test cases run before release, but product quality doesn’t improve.&lt;/li&gt;
&lt;li&gt;You don’t succeed at increasing the number of test cases run before release.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In all three cases, &lt;em&gt;you can stop worrying about how many test cases ran&lt;/em&gt;. The only case for keeping it around as a metric is in the 1st scenario so you can be alerted if the number regresses, but the longer you keep a metric like this around as a target, the more likely it starts being manipulated. The effects of Goodhart’s law are guaranteed to come into play eventually.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus tip: Know who you’re talking to
&lt;/h2&gt;

&lt;p&gt;A lot of my motivation for wanting to write this is that I’m a very quantitative person by nature. I have a hard science background and I like understanding things in terms of numbers where it makes sense to do that. If you’ve ever done corporate training on communication styles, you’ve almost certainly seen a 2×2 matrix dividing us all into 4 types of people. One quarter is always some version of “logical” or “analytical”, which is where I fall. These courses teach you that, even if you’re not that kind of person yourself, you’ll have more success communicating with people like that if you can put numbers on things. If you talk to someone in the opposing quarter — usually a Hufflepuff — you should leave the numbers out. Who is looking at a metric can be just as important as the metric itself.&lt;/p&gt;

</description>
      <category>culture</category>
      <category>measurement</category>
      <category>cemkaner</category>
      <category>communication</category>
    </item>
    <item>
      <title>What should the ratio of automated to exploratory testing be?</title>
      <dc:creator>Gregory Paciga</dc:creator>
      <pubDate>Tue, 24 Aug 2021 14:00:00 +0000</pubDate>
      <link>https://forem.com/gpaciga/what-should-the-ratio-of-automated-to-exploratory-testing-be-55lc</link>
      <guid>https://forem.com/gpaciga/what-should-the-ratio-of-automated-to-exploratory-testing-be-55lc</guid>
      <description>&lt;p&gt;I popped into an online panel about testing today, and a question along these lines was asked: what is the ratio between automated testing and exploratory testing at your company?&lt;/p&gt;

&lt;p&gt;I get the gist of what is being asked here of course, and wouldn’t get too pedantic in answering it in the moment, but this is my blog and I can get pedantic if I want. The interesting thing to me about this question is that even confining it to a single company, single team, or single product, there are many different ways to answer it. The crucial point is that for you to measure a ratio, you need to attach the same units to both quantities.&lt;/p&gt;

&lt;p&gt;One of my pet peeves is that tests aren’t countable things. Even strictly scripted manual tests usually have relatively arbitrary boundaries. Automated tests, especially UI tests, can typically be refactored in ways that change the number your tool reports at the end but contain the same set of assertions. (Even if you’re strict about saying one test has one explicit assertion, there are implicit assertions everywhere. Some tests might have 0 explicit assertions!) Even if you could count tests, how do you count &lt;em&gt;exploratory&lt;/em&gt; tests in any comparable way? Each session? Each charter? Certainly not per assertion because a human will make a hundred different “assertions” in their head every minute. No, counting tests can’t be done.&lt;/p&gt;

&lt;p&gt;Even asking about relative &lt;em&gt;coverage&lt;/em&gt; of the two approaches requires some underlying quantifiable thing to cover. I generally work in an environment where implicit requirements far outnumber anything explicitly written down. You may have some set of user stories, BDD scenarios, or other itemized list you can go through, but it’s unlikely many of them fall squarely into automated vs exploratory buckets. (I’ve rarely automated tests for features I didn’t also explore myself.) Can you even say a user story is 80% tested with automated tests and 20% with exploratory? 20% &lt;em&gt;of what&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;Maybe you can try to use time spent. I should be able to roughly say how much time I spent exploratory testing, at least if I’m good about time boxing and not getting distracted too much. How do you measure the time of automated testing? Should I could how long I spent writing test automation, or running it, or analyzing the results? Let’s say, I typically spend 1 hour writing code and 2 hours doing an exploratory session, so the ratio would then be 1:2. Does that ratio tell me anything interesting?&lt;/p&gt;

&lt;p&gt;One thing it certainly &lt;em&gt;doesn’t&lt;/em&gt; tell me is how much of my testing work is done by automation, or the relative importance of those two activities. In that one hour I might have added a handful of scenarios to an enormous test suite that takes 8 hours to run. I don’t &lt;em&gt;personally&lt;/em&gt; spend 8 hours on running that automation; I can do other things while the computer does that work. In that sense, investing more time into automation can actually &lt;em&gt;decreases&lt;/em&gt; the automation-to-exploratory ratio. If automated tests are already quire thorough and robust, those tests alone could be enough to release and the exploratory work is gravy. At the other extreme, the automated tests might still be too immature to tell me much useful yet and the exploratory tests are the crucial part.&lt;/p&gt;

&lt;p&gt;You could, perhaps, get into questions of how much time automated testing saves you compared to doing all of that manually. (Let’s hope that you would never actually try such a thing.) But then, we’re starting to talk more about automated vs &lt;em&gt;scripted manual&lt;/em&gt;, and on how you might measure ROI of automation. Both are totally different beasts.&lt;/p&gt;

&lt;p&gt;In reality, I expect most people would answer the question with some ratio of “human time” spent, and I’m thinking about it too much. Nobody asked for units.&lt;/p&gt;

&lt;p&gt;The question is really asking about strategy: How do you balance these two activities to be most effective? There’s no one way to objectively measure that, as it depends on what you care about. Are you asking how much time should be spent on automation? Are you asking about relative importance? Are you asking about what &lt;em&gt;can&lt;/em&gt; be automated or what &lt;em&gt;should&lt;/em&gt; be explored? Are you just trying to plan how many people you need on a project? Your priorities will determine which way to quantify these things.&lt;/p&gt;

</description>
      <category>automation</category>
      <category>generaltesting</category>
      <category>measurement</category>
      <category>questions</category>
    </item>
  </channel>
</rss>
