Friday, May 20, 2016

Post #5 of 6: Good Code Practices for Quality Automation


If MetaAutomation is too much change for right now…

Start with making your code as good as it can be.

I quote Elisabeth Hendrickson in the book on MetaAutomation:

It is tempting for organizations to treat infrastructure code as somehow inferior to production code. 'It's just scripts,' they say. 'We don't need to put seasoned engineers on it.' However what I've seen is that the infrastructure code -- that includes build and CI scripts as well as tests and test frameworks -- is the foundation on which the rest of the code is built. If the infrastructure code is not treated with the same care as production code, then everything is built on a shaky foundation.

Teams should follow the team’s adopted practices for product code where it makes sense, but also consider making some changes for quality automation code:

·       Some types of security and performance considerations for product code might be unnecessary in quality automation code, since the latter will never ship outside the team’s control.

·       Consider using some structures to help with quality automation-specific code, e.g., to make the actions of driving the product self-documenting in detail. The sample projects on http://MetaAutomation.net show many details on this.

Here too, there are more details in the book on MetaAutomation.

If you have a choice, use a compiled language. The idea that an interpreted language like Python can make QA engineers more productive is an illusion, because not having a compiler on your side can result in runtime failures that a compiler would have caught, causing significant time and cost in following up. An interpreted language lets one write code faster, but that’s not the whole value story. A compiled language like C# will tell you about all sorts of problems immediately, and many others almost immediately and certainly before committing code to a repository. This saves a lot of time.

As a counter-example, I’ve also used Ruby to do quality automation, and among many other shortcomings of this language, it effectively hid problems from me until much later than writing the code, causing significant cost and frustration.

Consider using the same language as the product code, so less information gets lost at the boundary between the product and quality automation code driving the product, the dev role can contribute as needed to quality automation, and the QA role can know more of the product and even contribute to the product as needed.

Personal anecdote: I’ve added XSL code to a product, mainly written in Java, to make an important product web site vastly more testable using both Java and XSL in the quality automation code. This kind of thing is much easier if the languages are common between quality automation code and product code.

Careful to avoid copy-and-paste code; this causes maintenance cost, because the code might have to be updated in multiple places (since the same code is copied multiple places) and if the coder misses one or more of the copies, more wasted time and cost result.

For checks that use a GUI or a web browser, always synchronize to objects or events if possible, rather than sleep. This will help performance and reliability of the checks.

A few more minor points:

·         Maximize code reusability and reuse.

·         Make symbol names descriptive, so code becomes self-documenting.

·         Comment code but only if needed, and always at one level of abstraction above the code itself.

·         Always do code reviews! It’s an opportunity to learn from each other and raise code quality and uniformity across the team.

This page is #5 in a series of six, with the original post here.

Thursday, May 19, 2016

Post #4 of 6: Make Your Checks Simple


If MetaAutomation is too much change for right now…

Make your checks simple, to improve scalability of your check runs with more resources and to improve the business value of your quality data. (OK, that’s “improve the quality of your quality data” and yes I know that might sound silly.)

There is a pattern called “Chained Tests” that occurs in the wild, and described here: http://xunitpatterns.com/Chained%20Tests.html but it’s actually a very bad idea. I’d call it an antipattern. The linked page goes into the negatives a bit, but I will add a more modern reason to NEVER chain your tests: they won’t scale. Chained tests must be run in a sequence, so it doesn’t matter how much computing resources you allocate, the check (aka “test”) run won’t go any faster.

As an extension of the “scalability” reasoning, make your checks simple. Each check should have no more than one target verification or verification cluster, and NOT have superfluous verifications that can either slow the check down and/or make it less robust and more fragile than it would otherwise be.
Here is a color version of one of the diagrams illustrating the Atomic Check pattern in the book on MetaAutomation:



Another way to simplify the checks, and make them faster, is to use the Precondition Pool pattern of MetaAutomation.

This page is #4 in a series of six, with the original post here.

Wednesday, May 18, 2016

Post #3 of 6: Make your check fails self-documenting


If MetaAutomation is too much change for right now…

Verify that you’re doing all you can to minimize debugging costs, in case of check failure.

1.       Add preliminary verifications wherever null-reference exceptions occur

A null-reference exception (or null-pointer exception for a native language) will lose information: which symbol was null? There is often more than one possibility on a given line number. If there’s an ambiguity, it might require a debug session to find out, and in some cases, the line number might have changed for the version of the code you can access versus the one that was running and threw the exception.

Labeled preliminary verifications, e.g., asserting non-null “<some API> returned null>” will find the condition sooner and show it with much better specificity than if there were no such verification. With complex code this can make the difference between a clearly understood root cause of check failure, and a very confused one.

If there isn’t a preliminary verification for where the null could potentially happen, and the check failure can’t be reproduced easily, a debug session can be either very expensive or even useless, meaning that the information of the failure is lost forever.

2.       Verify that asserts or verifications are self-documenting

Labels for thrown exceptions add value in two ways: First, they describe what happened, to make resolution of a check failure easier, and second, they ensure that there is no ambiguity of where or under what circumstances the failure occurred. Using the built-in exceptions can make sense for produce code where the standard for performance is high, but for quality automation code, use an assert or a custom exception to make the failure explicitly self-describing.

3.       Add more log statements around points of failure

Consider the difference in cost between adding a few more log statements around parts of checks that are likely to fail, and reproducing and debugging through the failure, maybe more than once, especially if the failure is hard to reproduce.

Adding log statements is much cheaper and lower-risk.

4.       Make all checks fail on an exception, even negative cases

For negative checks that are expected to fail, enclose the expected failure in code that verifies the expected failure condition, then throw another exception in case of failure to fail the check.

Exceptions are intended to be used in exceptional circumstances. Overuse of exceptions, or too much code that is expected to be bypassed in case of an exception, reduces reusable code in the quality automation infrastructure because a new pattern would be required for coding the negative check method signatures, and makes any cleanup more complex.



The Atomic Check pattern of MetaAutomation shows how to do all this with much more structure, transparency, and detailed hierarchical self-documenting check code.

This page is #3 in a series of six, with the original post here.


Tuesday, May 17, 2016

Post #2 of 6: Basic Check Design


If MetaAutomation is too much change for right now…

Here are some easy steps to take:

1.       Make your checks independent of each other.

This is how checks can be fast and scalable: they must be independent of each other. Even the simplicity of the checks depends on them being independent of each other, and in remember in case of a failure, the value of what a check can find can depend on simplicity, because with long or complex checks, things can get muddy and any business value can be clouded and even lost because it becomes too much work to debug through the check to try to get the actionable information out, surface it and describe it for the benefit of the larger team.

This is a core principle of the Atomic Check pattern of MetaAutomation: all checks are independent of each other. This is how checks can scale across resources. If the “Chained Tests” antipattern is still used, checks can’t scale at all because they still have to happen in a time sequence, and any failure might depend on an operation earlier in the sequence, so the value of any issues found depends first on a lot of work to reproduce that sequence of operations.

2.       Prioritize your checks based on business requirements (or even functional requirements)

It seems obvious, doesn’t it? Prioritize… work on the more important parts of your product first.

If your team doesn’t have business requirements, you probably don’t know what you’re building, and the risk is that you’re building the wrong thing for your customers. See the excellent book by Robin Goldsmith on this topic, for example.

At least, however you’re defining your requirements (e.g., with user stories), prioritize them and prioritize your checks based on requirements.

This is part of the Atomic Check pattern as well.

3.       Ensure that your automated checks are completely repeatable. If needed, record the parameters used so you can repeat them as needed.

Whether or not you’ve ever had a failure in any one check, you need to be able to repeat the check exactly.

Otherwise, you can’t be sure that quality is always getting better because what aspect of quality you measured before isn’t necessarily the aspect you’re measuring now, and maybe you just got lucky today.

In case of failure, you need a record to do the failure again, or if you can’t reproduce it, go looking for what the real problem is, e.g., a race condition somewhere.

This is part of the Atomic Check pattern as well.

4.       Move setup and teardown operations out-of-line.

Any check might have preliminary setup steps and/or tear-down steps that can be moved out-of-line. The question is this: can any setup or teardown be done asynchronously and in some other process, in some other memory space?

For example, allocating and initializing an environment in which to run a check; that should be done out-of-line.

Allocating, initializing or re-initializing a user identity: that should be done out-of-line.

Any other state for the check, e.g. some file image or system state, that can be done out-of-line and out-of-process, should be done that way, because it means that your checks can run faster and more scalably.

The Precondition Pool pattern of MetaAutomation addresses this.

This page is #2 in a series of six, with the original post here.

Monday, May 16, 2016

Post #1 of 6: If MetaAutomation is too much change for right now…


Most of the patterns and values of MetaAutomation depend on the pattern Atomic Check, and Atomic Check might be a significant change from the way you do quality automation right now.

So, if you’re not ready to take on the big change right now, what can you use of MetaAutomation right now to improve your quality automation?

Following is a series of five blog entries to address some low-cost things you can do to improve the value of your quality automation.

Tuesday, April 19, 2016

The New Pattern for Quality Automation


There’s a new pattern in town. Actually, it’s a pattern language called MetaAutomation, composed of six patterns, every one based on existing patterns of problem solving in information technology (IT) but with the addition of World Wide Web Consortium (W3C) XML technologies to make them much more powerful in combination.

The existing pattern “Test Automation Framework” (TAF) (Meszaros, “xUnit Test Patterns,” 2007, p. 298) describes existing practices for driving and measuring a software product under development. This works, and it delivers value of course, but it’s limited. With TAF, for example:

·         The customer of the information is people on the QA team. Somebody on the QA team must manually interpret and present the information to the wider software team.

·         The difference between what a human tester and an “automated test” can do is not addressed, causing business risk and opportunity cost.

·         The issues of blocked product quality measurements due to failures and flaky checks is not addressed.

·         The issues of prioritization of measurements is barely addressed.

·         The goal of actionable check failures is not addressed.

MetaAutomation solves all of these problems, and more:

·         MetaAutomation brings a much higher level of visibility and respect to the QA role

·         MetaAutomation brings higher visibility to the developer role

·         MetaAutomation breaks down silo walls with speed and transparency

·         MetaAutomation shows how a single check can drive and measure an Internet of Things (IoT) product on multiple tiers

The costs of MetaAutomation? First, take on some paradigm shifts. These are enumerated on http://MetaAutomation.net.

Second, the quality automation code needs as much care and detail as product code. The team needs at least one person with software development skills to be a part of the QA team or role. There are working solutions available for free on http://MetaAutomation.net.

The diagram below shows how the six patterns of MetaAutomation compose to form the pattern language, and how they fit in the context of the business space. The TAF pattern addresses the QA role, but MetaAutomation delivers value all across the team, even up to the executive suite for Sarbanes-Oxley (SOX) compliance.





For more information on MetaAutomation, see http://MetaAutomation.net. For even more information, see the book MetaAutomation 2nd Edition

Thursday, February 18, 2016

DevOps needs MetaAutomation for Quality


DevOps emphasizes collaboration and communication between all members of a software team, including leads, designers, devs, QA and test people. (See the Wikipedia article on DevOps.)

It needs speed and reliability.

A weak quality practice won’t work – regressing and testing can take huge amounts of time, and measuring software quality is more difficult if it’s hampered by outmoded ideas, e.g. “The point of Test is to find bugs,” or “Test automation does what manual testers do, but faster and more reliably … we hope.”

MetaAutomation shows the way to the powerful quality automation that DevOps needs:

1.       The team knows exactly what is measured by the automated checks, and what is not

2.       With self-documenting hierarchical check steps that report “pass,” “fail,” or “blocked” for each step, the correctness of product behavior is clear from the business-facing view and the granular technology-facing view

3.       Since the artifacts (results) of the check runs are pure data, presentation is completely flexible, and analysis is robust

4.       The manual testing role never has to repeat tedious steps, so they can do what they’re good at, which is more fun and satisfying anyway

5.       The QA team delivers quality measurements with speed, accuracy and precision, earning the respect and esteem of their fellow team members

6.       Checks can be run across tiers and devices, with unified artifact results, to make quality measurement simpler, more robust, and less risky

7.       Check runs scale with resources, so results are available almost arbitrarily fast, giving transparency and trust to the rest of the team

Check out http://MetaAutomation.net for more information, and some complete open-source sample implementations with reusable components.

Tuesday, January 5, 2016

The Paradigm Shifts of MetaAutomation

The current paradigm of functional software quality is in crisis.
“Test automation” is broken. It’s not that it doesn’t bring some value – it does! – but we in the field all know of the many test automation projects that have failed to deliver. The current paradigm is in crisis. It’s time to look again.
The following is extracted from my draft of Chapter 2 of the 2nd Edition of MetaAutomation, due out in February or March. Interested engineers can also check out http://MetaAutomation.net, and the working samples there that illustrate the radical benefits of MetaAutomation.

Paradigm Shift 1: Automated Verifications, aka Checks, Are Very Different from the Manual Test Role

Traditional model: automated tests are just like manual tests, but faster.
New paradigm: automated verifications are different from manual testing in almost every way.

Paradigm Shift 2: Focusing Checks On Their Unique, Important Capabilities Vastly Increases Business Value

Traditional model: Manual test cases, and automation of same, provide the model and limits for measuring quality.
New paradigm: When quality automation moves away from focusing on making the system under test do stuff and towards measuring and communicating quality, it can provide much greater business value than with current practices.

Paradigm Shift 3: Checks are Bounded in Time, Enabling Structured Artifacts

Traditional model: Checks generate logs, just like any other ongoing process.
New paradigm: Time-bound checks enable robust, structured artifacts with self-documenting steps, vastly increasing the value of the check artifacts.

Paradigm Shift 4: Hierarchical Steps Give Transparency, Robustness, and Flexibility

Traditional model: Check steps are a linear list.
New paradigm: Check steps can be self-documenting and hierarchical, enabling business-facing steps as parents and technology-facing steps as children.

Paradigm Shift 5: The Internet of Things is Distributed, So Measure Quality That Way Too

Traditional model: Automation of a product is limited to one tier for any given check.
New paradigm: Structured data allow any check to manipulate and measure across any number of tiers, enabling end-to-end checks for the Internet of Things.

Paradigm Shift 6: Better Quality Data leads to Quality Power Across the Team and Across the SDLC

Traditional model: Checks described with business-facing terms allow all team members to consume results, but require the QA role to maintain and hide the details of what’s going on.
New paradigm: With hierarchical self-documenting check steps, nothing is hidden and everything is exposed to any team member that wishes to drill down from business-facing parent steps to the child-most steps that describe atomic operations on the product.

Wednesday, October 28, 2015

Analytics and MetaAutomation


Analytics are very powerful and an awesome developing technology, and your team needs automated verifications of business requirements as well (e.g. using the Atomic Check pattern of MetaAutomation, and dependent patterns).

Why both?

Atomic checks are fast and reliable enough to verify requirements from an end-user perspective quickly, and a set of them are even fast and scalable enough to gate check-ins (especially with the Precondition Pool, Parallel Run and Smart Retry patterns of MetaAutomation). Implementing these patterns can ensure that quality is always moving forward, which is especially important for software that matters.

Analytics can give the team ideas of what the end uses are experiencing. This is awesome, because otherwise you’d have little or no idea of what’s going on for your end users. This is very valuable for, e.g., A/B testing. OTOH, it’s somewhat like the shadows of Plato’s cave: you have to reconstruct and guess what’s really going on in some cases, e.g., through session abandonments on a site.

Analytics need product instrumentation, aka telemetry. Good news; there’s synergy here! Automated verifications can use those as well. Analytics benefits from product instrumentation through logs, and automated verifications can use the same outputs but synchronized for inclusion in the artifact of a check run. The valid XML document created by an atomic check is ideal for this.

 

This diagram gives a view of how product instrumentation can benefit both analytics and automated verifications (checks).

Tuesday, October 27, 2015

Automated Verifications Deserve Better than Flight-Recorder Logs

This post is a follow-up from this one:
http://metaautomation.blogspot.com/2015/10/linear-check-steps-are-good-but.html

"Automated Test" is an oxymoron, because you're not automating what a manual tester could do with the script, and unlike true automation (industrial, operations or IT automation) you don't care about the product output (unless you're doing your quality measurement that way explicitly).

Automation for software quality has some value at authoring time because it's a good way of finding bugs, but really it only has business value with the verifications being done, most of which are coded explicitly (preliminary verifications, and a target verification or verification cluster, per MetaAutomation).

So, call it what it is: automated verifications! That understanding opens up tremendous business value for software quality! If done right, it can help manual testers too by making their jobs more interesting and more relevant.

According to tradition, and according to the origins of "test automation" from industrial automation, the output of automation the software system under test (SUT) is flight-recorder logs and, maybe, a stack trace. But, there's no structure there; it's just a stream of information, some relevant, but most not relevant or interesting.

It's time to leave that tradition behind! Automated verifications have well-defined beginnings and ends. They're bounded in time! Use that fact to make some structure out of the artifacts, i.e., the information that flows from an automated verification.

XML is ideal for this, especially with an XSD schema. With an XML document, there are boundaries and a hierarchical structure, and if the presentation is left out (as it should be) then it's pure data; it's compact and strongly-typed, available for robust and efficient analysis, and completely flexible for presenting the data.

Even better: The least-dependent pattern of MetaAutomation, Atomic Check, shows how to write self-documenting hierarchical steps for your checks (i.e., automated verifications) which means that you'll never have to choose between using your teams domain-specific language (DSL) or ubiquitous language, and using those (sometimes, very important) granular details of what the check is doing with your product or where/why it failed. You can do both!

With self-documenting hierarchical steps, after a given check has succeeded all the way through at least once, if the check fails, all the check steps are recorded with "pass," "fail," or "blocked." This gives another view of course on what the check was trying to do and tells you exactly what parts of product quality are blocked or not measured due to the failure.

Self-documenting hierarchical steps also give you information that's detailed and precise enough to know whether the specific failure has happened before! See the Smart Retry pattern of MetaAutomation for how to do and use this.

Even more: using a structure like XML for your check artifact means that you have a ready placeholder for perf data; it's recorded how many milliseconds a given step took, for every step in the hierarchy. Perf testing doesn't need a separate infrastructure or focus, and perf data is available for robust analysis over the SDLC.

See the samples on MetaAutomation.net to see how this works.