Announcing: New Google C++ Testing Framework



We all know the importance of writing automated tests to cover our code. To make it easier for everyone to write good C++ tests, today we have open-sourced Google C++ Testing Framework (Google Test for short), a library that thousands of Googlers have been using in our C++ programs. Highlights of the project include:

  • Google Test is portable: it works on a variety of platforms (Linux, Windows, Mac OS X, and more), with several versions of GCC and MSVC compilers, and with or without exceptions. You can even use it in embedded systems like Windows CE and Symbian. Build tools and test runners for many of these are under active development, with Linux Autotools support already in place.
  • It supports both fatal and nonfatal assertions. The test will continue after a nonfatal failure. This allows more problems to be uncovered and fixed in a single edit-compile-test cycle.
  • It provides many assertions for common testing needs, and lets you easily define new assertions for less common cases.
  • On Linux, you can write death tests to ensure that your code crashes with expected errors.
  • Because it's based on the popular xUnit architecture, Google Test is easy to learn if you've used any testing framework in this family before.

It will take you about 10 minutes to learn the basics and get started. Stay tuned to this blog for helpful Google Test information in upcoming Testing on the Toilet episodes.

Please send questions and feedback to googletestframework@googlegroups.com (the Google Test Discussion Group). See you there!

Permalink | Links to this post | 9 comments

Defeat "Static Cling"

You're pair programming and, as many brilliant people are apt to do, talking out loud. "I'll make a mock, inject it, and rerun the test. It should pa- ...D'OH" Your partner notices the exception "ConnectionFactory not initialized". "What?" she says, "Something is using the database? Dang, and this was supposed to be a small test."

Upon inspection you find that your class is calling a static method on some other class. You've got Static Cling! If you're (ab)using a data persistence layer that generates code which relies on static methods, and weren't careful, your code might look something like this:

public class MyObject {
  public int doSomething(int id) {
    return TheirEntity.selectById(id).getSomething();
  }
}



As a result, you can't call doSomething without calling TheirEntity's static method. This code is hard to test because static methods are impossible to mock in Java.

So, how do you get rid of this form of Static Cling and get that small test to pass? You can use a technique sometimes known as the Repository Pattern, a form of Abstract Factory. Create an interface and an implementation with the unmockable static method calls:

interface TheirEntityRepository {
  TheirEntity selectById(int id);
  // other static methods on TheirEntity can be
  // represented here too
}
public class TheirEntityStaticRepository
        implements TheirEntityRepository {
  public TheirEntity selectById(int id) { // non-static
    return TheirEntity.selectById(id); // calls static method
  }
}



Next, inject a TheirEntityRepository into MyObject and use it instead of calls to the static method:

public class MyObject {
  private final TheirEntityRepository repository;
  public MyEntity(TheirEntityRepository arg) {
    this.repository = arg;
  }
  public int doSomething(int id) {
    return repository.selectById(id).getSomething();
  }
}



You can do this even if you don't have access to source code for TheirEntity, since you're not changing the source itself, but merely encapsulating its static methods in an injectable interface. The techniques shown here generalize to the case where a static method acts as a Factory of objects.

Now you can inject different implementations of the repository for different tests, such as "never finds anything," "always throws an exception," "only returns a TheirEntity if the id is a prime," and so forth. These kinds of tests would've been impossible before this refactoring.

Remember to download this episode of Testing on the Toilet and post it in your office.

Permalink | Links to this post | 3 comments

Test Engineering Class Project at UC-Irivine

Posted by George Pirocanac, Test Engineering Manager

For the past nine months it has been my pleasure to work with a group of undergrad students from UC-Irvine as part of their senior class project. The course was run by professor Hadar Ziv and teaching assistant Sameer Patil. It focused on providing students industry experience by working with customers (in this case us) to formulate product requirements and deliver working software. Jason Robbins from the Google Irvine office was the lead for another project and several other local companies also participated.

Our team members included Michelle Alvaraz, Jason Dramby, Peter Lee and Gabriela Marcu. It was the only project dealing directly with test engineering and one of our goals was specifically to create a plan and framework for testing the Google Mashup Editor (GME) tag language.

For those unfamiliar with the GME, it is a framework for developing simple web applications and mashups using a custom set of XML tags, Javascript, CSS and HTML. More information about the GME can be found here.

The first three months of the class were spent learning about the the GME and performing exploratory testing. The team became very familiar with the editor and created several mashups (You can try one of them here.). They also created a traditional test plan which focused on testing the tag language. Later they executed this test plan by compiling and running their sample mashups on a variety of browsers.

After a couple of iterations of this test plan they quickly encountered some of the typical challenges associated with the traditional approach - namely human resource oversubscription in test execution and insufficient coverage.

We addressed with the first issue through automation and the team learned to automate their manual tests of the mashups with Selenium. They first used Selenium IDE to learn the basic Selenium commands and concepts such as locators. Afterwards they used the "Export Test As..." feature in IDE to create Python tests that would be run under a local server with Selenium-RC. The latter got them to a point where they could execute the existing test plan
automatically on three different platforms (Windows, Linux, MacOS).

Expanding coverage was less straightforward. The traditional approach would be to use the existing resources to write more tests. We, however, decided to create a framework that would itself generate more tests. This dovetailed nicely with the classroom material which was product-centric and focused on gathering customer requirements, creating a design document and delivering the software. In our case, the group's product was to be a GME Test Suite Creator.

As a starting point we looked at the following simple Python script which creates a simple cross product on lists of strings:

#!/usr/bin/python


def cross(args):

ans = [[]]

for arg in args:

ans = [x+[y] for x in ans for y in arg]

return ans


def pprint(lists):
for list in lists:

a = ''

for s in list:

a = a + s

print a


tags = [ ['<'],

['gm:page '],

['', 'authenticate=true', 'authenticate=false',
'authenticate=invalid'],

['/>'] ]


lists = cross(tags)

pprint(lists)


Running the script yields the following combination of tags:

< gm:page />
< gm:page authenticate=true/>
< gm:page authenticate=false/>
< gm:page authenticate=invalid/>


Each one could be used in a mashup that used the page tag. Likewise, the other tags from the GME tag language could be expanded with various combinations of valid and invalid attributes. These tag combinations could then be individually inserted into skeleton mashups producing a large number of both positive and negative tests which would be performed under Selenium-RC.

This was the basic idea of the GME Test Suite Creator and the team implemented a GUI to facilitate the three steps in creating and running a testsuite:

  • Code Generation - The selection of tags and creation of tests.
  • Code Preview - The examination and execution of created tests
  • Test Reporting - The examination of test results.

The figure below shows the Code Generation tab of the GME Test Suite Creator. It displays a hierarchical view of the tabs and allows the user to select which tags to include in the sample tests. The sample test is generated from a skeleton test modeled after the documentation example scraped from the code.google.com website. This was a nice idea which added testing of the documentation to the process.

An interesting problem that these types of automatic test generation frameworks can encounter is the combinatorial explosion of generated tests. For example, if each tag attribute can have 8 possible values and a sample mashup contains 10 tags, enumerating each combination would take roughly 1 billion (810 = 230) tests! To address this, the team created an Options dialog box that would allow the user to specify different test suite sizes in addition to the test suite name and type. A further refinement, allowing the user to select which set of specific values to use for tag attributes would have been implemented if the team had more time.

The next figure shows the Code Preview tab of the GME Test Suite Creator. It shows the list of tests created under a given test suite and allows the user to manage and execute the test suite.

Finally, the Test Report Tab shows the results of the tests executed under Selenium-RC.

GME Test Suite Creator was itself written in Python and hosted on Windows, Linux and MacOS.
The team presented and demonstrated the GME Test Suite Creator to faculty and other student/industry teams as part of the UC-Irvine ICS Student Show Case. Over the next few weeks I will be kicking the tires and evaluating the battle worthiness of the GME Test Suite Creator delivery which included source code and a complete set of documentation.

I certainly had a wonderful time interacting with the team and participating in this program!

The GME Test Suite Creator Team (from left to right: Gabriela Marcu, Peter Lee,
Michelle Alvarez, Jason Dramby and George Pirocanac)

Permalink | Links to this post | 3 comments

Productivity Games – Using Games to Improve Quality

Editor's note (Pat Copeland, Engineering Productivity Director, Google): On occasion we ask a special guest to post on an interesting topic. Ross has some really interesting ideas about how to use games to influence behavior. I'm a big fan. Enjoy!


Ross Smith, Director of Test, Microsoft Windows Core Security

“Quality takes you out of yourself, makes you aware of the world around you.” [1]


The “Gamer Generation” is here. According to the Washington Post, in 2006 at least 40% of Americans play video games on a computer or a console. The largest demographic is 18-34 year-olds, many of whom are working as our friends and peers as software developers and testers. There is a great book, Got Game, which describes the impact of games on the workforce of today and in the future.

Many businesses are wondering these days how to use simple concepts popular in video games and apply them to work.

It’s happening already. From a construction site with a sign posted with “days since last accident” to the car dealer with salespersons leader board scrawled out in chalk. Simple competition helps work get done in all kinds of industries. The success of sales contests is a great example of how well competition works.

“In every job that must be done, there is an element of fun. You find the fun and—SNAP—the job’s a game!” —Mary Poppins

A company called Seriosity has made interesting use of video game concepts at work with their application of virtual currency to email. To help with information overload from an overflowing inbox, email senders can “spend” virtual currency (Serios) to help prioritize their messages. Spending to denote the importance of a message is not a whole lot different than buying new golf clubs with virtual money earned in a Tiger Woods game, buying new tires in a car racing game – or using gamer points to upgrade your armor in an RPG (Role-playing Game). Wired Magazine had a great article on the use of WOW as a leadership training game. Playing games at work is more than just a quick game of online Hearts with one finger on the “boss key”. Games at work can have real impact.

With other industries using productivity games, what about software development? How can productivity games help testers improve the quality of the products they test? One of the more famous test techniques is the bug bash. Teams pick a certain date, and everyone bangs on a certain area of the product to find bugs. At the end, prizes are awarded while everyone enjoys pizza and drinks. That sounds a lot like game, doesn't it? It’s also a perfect example of a simple productivity game.

As the world of software gets more complex and the test matrix grows, there is no shortage of opportunities for testers to do more testing. Quality is always “improved”, it’s never completed, fixed or finished. Therefore, testers must choose from a variety of techniques and activities to pursue tasks with the highest return and value. In 1990, Harry Markowitz won the Nobel Prize for his work on Portfolio Selection (that he began in the 1950’s). The theory, familiar in financial markets and mutual funds, is that a portfolio of diverse assets with varying risk and returns actually reduces risk in time uncertain conditions. Testers can benefit from the work on portfolio selection by varying the techniques they use to find defects. However, some techniques are more expensive, more difficult, or less attractive than others. Some teams, in some situations, can rely on the altruism and volunteer efforts – organizational citizenship behaviors – of their members to take on the more difficult tasks. However, that doesn't always work, and other incentives may be required. That’s where productivity games can help.

When a project needs a bit of a push towards a certain behavior, building a game around it can help. For example, if a test team wants to improve the usage of unit tests by developers, encourage the team to “eat their own dogfood” or run automated tests on personal machines overnight, then creating a game will help people’s motivation can motivate people to participate in those activities.

Productivity games differ from traditional games in a few distinct ways. The goal of a productivity game is to attract players. These games don’t need winners as much as they need players. In many cases, productivity games don’t even need prizes. Productivity games can be simple. There’s no need to invest in expensive graphics or 3-D modeling – people play the game to compete around a work activity, not because of the appeal of the user interface. A simple leader board might be all that’s needed.

Using games at work is a powerful and effective method to influence change in organizational behavior, and therefore requires care in the design and use. It is possible to overdo the use of games to a point where they are counter-productive or ineffective. Successful game design is best achieved through experience and experimentation, and the goal should be to keep things interesting enough to always attract players. A game where one player leaps out to an insurmountable lead is not effective, because that will discourage others from playing. When a team wants to encourage testers to invest in fault injection techniques, setting up a leader board with bug totals found via fault injection techniques will attract attention of other testers, often just by word-of-mouth. You should encourage team-wide competition, smack talk, and public embarrassment as a means to draw attention. Games should be short in duration. Many testers remember the Dilbert “I’m gonna write me a new minivan” from 11/13/95. This is what results from a poorly designed productivity game.

Productivity games are great at motivating people to do things and change behavior. And as Uncle Ben said to Spiderman, “With great power comes great responsibility”. It’s critical to have specific goals for the games, and to understand the impact before deploying a game – it’s pretty likely that people will play, at least initially, and the impact may not be what you intended. Keep the duration of games short in order to be able to adjust. And finally, keep the games focused on volunteer or “extra” activities. A game designed around an individual’s job or portions of everyone’s regular job can introduce unusual feelings when it comes to rewards and performance evaluation. It’s easier to steer clear of that than to try to figure out the right balance.

Shigeru Miyamoto, who designed Super Mario Bros., talks about games as “miniature gardens”, metaphorically representing the cultural values, humanity, and challenges of everyday life the way a miniature garden might represent a real one.

The whole idea, for me, is about the exploration of a hakoniwa, a miniature garden. It's like a garden in a box, where if you look at it from different angles, you can see different plants and arrangements. And you have that sense of surprise and exploration. There's always things you can find. [2]

Games are a lot like testing. Software quality assurance and testing efforts represent a proxy for real users in much the same way that games are a proxy for the real world. The challenges that Mario faces with fire-breathing dragons and knife throwing turtles are balanced by the allure of coins and princesses. A testing organization has a good idea of the tools available in their portfolio to improve quality and eliminate those “fire-breathing dragons” for their customers. Productivity games allow teams to offer coins and position rewards around their equivalents of Markowitz’s “diverse assets” at their disposal, in the form of defect detection and removal techniques, to improve quality.

For the players, productivity games offer people the ability to learn, solve problems, and earn a reward. They offer a way to challenge players to compete, to explore and discover, and to establish a surrogate identity or status via a leader board. There are many fundamental motivations to play a game. “If you build it, they will come [3]." A good productivity game designer can build a game around “work that needs to be done that no one wants to do” – and like the lone teenager who plays Halo for weeks on end, people will take on that work. Experiment and explore – the results can be surprising.

I’d be interested in any comments about Productivity Games that you might have.

Thanks,

Ross Smith

http://www.defectprevention.org/

Interesting Links:

When Work becomes a Game

Serious Games Initiative

Got Game - How the Gamer Generation is Reshaping Business Forever

Chapter 5 – Productivity Games - The Practical Guide to Defect Prevention

2008 Serious Games Summit presentation

Miniature Gardens and Magic Crayons: Games, Spaces, & Worlds

HBR Leadership’s Online Labs

NPR: Software lets users assign value to email

Game Tycoon blog (How Video Games are transforming the Business World)

Productivity Games Blog

The Levity Effect

Special thanks to Joshua Williams for his help with this post.



[1] Robert Pirsig, Zen and the Art of Motorcycle Maintenance
[2] Wired Magazine Interview http://blog.wired.com/games/2007/12/interview-super.html
[3] Field of Dreams, 1989

Permalink | Links to this post | 2 comments

Taming the Beast (a.k.a. how to test AJAX applications) : Part 1

Posted by Markus Clermont, John Thomas

This is the first in a two part blog series titled 'Taming the Beast: How to test AJAX applications". In this part we discuss some philosophies around web application testing and how it should be done the 'right' way. In part 2, we walk through a real example of designing a test strategy for an AJAX application by going 'beyond the GUI.'

Background
Typically we address the problem of testing an AJAX application through a plethora of big end-to-end tests and (hopefully) high unit-test coverage. Here we outline the main problems with this approach and demonstrate an effective testing strategy for a sample GWT-based application which goes beyond "testing just through the GUI."

Problems with GUI-only testing

In general testing through the GUI:
  • is expensive (takes long to write the tests and execution is resource-intensive)
  • gives limited insight into the system
  • often take only the 'happy paths' into account
  • combines multiple aspects in a single test
  • is slow and brittle
  • needs a lot of maintenance
  • is hard to debug

And while unit tests don't suffer from many of these problems, they alone are not sufficient mainly because they:
  • give little insight how the components interact with each other
  • don't give confidence that the business logic and functionality of the system meets the requirements

Solution
Although there is no 'one size fits all' solution, there are some basic principles we can use to solve the testing problem for web applications:
  • Invest in integration tests (identify the smallest sub-system)
  • Separation of Concerns (don't do the set-up through the interface you are testing)
  • Test each interface separately (mock out everything that you are not testing)
  • Consider dependencies in production (figure out how dependencies can fail, and test that)
  • Use a mix of strategies and tools. There is no silver bullet.
  • And no... you cannot scrap all of your end-to-end tests

A recipe for testing goodness
Using the principles above we can build up a recipe for testing web applications. In the second part of our blog we will walk through each of these steps for a real web application.
  1. Explore the system's functionality
  2. Identify the system's architecture
  3. Identify the interfaces between components
  4. Identify dependencies and fault conditions
  5. For each function:
  • Identify the participating components
  • Identify potential problems
  • Test in isolation for problems
  • Create a 'happy path' test

End note: value of a test
A question commonly asked by developers when writing tests is, "is this really worth my time?" The short answer is "always!". Since fixing a bug is way more expensive than preventing it in the first place, writing good tests is always worth the time.

While there are many different classifications of tests, the most common way of classifying them is based on their size and the areas of a product they test. Each test answers specific questions about the product:
  • Unit test: is the method fulfilling its contract?
  • Small integration test: Can two classes interact with each other?
  • Medium integration test: Is a class interacting properly with all its dependencies? Does it anticipate and handle errors correctly? Are the needed functions exposed on an API/GUI?
  • Sub-system test: Can two sub-systems interact with each other? Does one of them anticipate all errors of the other and does it deal with them appropriately?
  • System test: Does the entire system behave as expected?
Keeping this questions in mind, testing at various levels allows us to write more focused and meaningful tests. Remember that effective tests are those that provide quick and useful feedback, i.e. quickly identify issues and pin point the exact location of the issue.

In the next episode we will walk through the recipe proposed above using a real web application.

Permalink | Links to this post | 5 comments

TotT: Friends You Can Depend On

When you want to test code that depends on something that is too difficult or slow to use in a test environment, swap in a test double for the dependency.
A Dummy passes bogus input values around to satisfy an API.


Item item = new Item(ITEM_NAME);
ShoppingCart cart = new ShoppingCart();
cart.add(item, QUANTITY);
assertEquals(QUANTITY, cart.getItem(ITEM_NAME));


A Stub overrides the real object and returns hard-coded values. Testing with stubs only is state-based testing; you exercise the system and then assert that the system is in an expected state.


ItemPricer pricer = new ItemPricer() {
  public BigDecimal getPrice(String name){ return PRICE; }
};
ShoppingCart cart = new ShoppingCart(pricer);
cart.add(dummyItem, QUANTITY);
assertEquals(QUANTITY*PRICE, cart.getCost(ITEM_NAME));


A Mock can return values, but it also cares about the way its methods are called (“strict mocks” care about the order of method calls, whereas “lenient mocks” do not.) Testing with mocks is interaction-based testing; you set expectations on the mock, and the mock verifies the expectations as it is exercised. This example uses JMock to generate the mock (EasyMock is similar):


Mockery context = new Mockery();
final ItemPricer pricer = context.mock(ItemPricer.class);
context.checking(new Expectations() {{
  one(pricer).getPrice(ITEM_NAME);
  will(returnValue(PRICE));
}});
ShoppingCart cart = new ShoppingCart(pricer);
cart.add(dummyItem, QUANTITY);
cart.getCost(ITEM_NAME);
context.assertIsSatisfied();


A Spy serves the same purpose as a mock: returning values and recording calls to its methods. However, tests with spies are state-based rather than interaction-based, so the tests look more like stub style tests.


TransactionLog log = new TransactionLogSpy();
ShoppingCart cart = new ShoppingCart(log);
cart.add(dummyItem, QUANTITY);
assertEquals(1, logSpy.getNumberOfTransactionsLogged());
assertEquals(QUANTITY*PRICE, log.getTransactionSubTotal(1));


A Fake swaps out a real implementation with a simpler, fake implementation. The classic example is implementing an in-memory database.


Repository repo = new InMemoryRepository();
ShoppingCart cart = new ShoppingCart(repo);
cart.add(dummyItem, QUANTITY);
assertEquals(1, repo.getTransactions(cart).Count);
assertEquals(QUANTITY, repo.getById(cart.id()).getQuantity(ITEM_NAME));


While this episode used Java for its examples, all of the above “friends” certainly exist in C++, Python, JavaScript, and probably in YOUR favorite language as well.


Remember to download this episode of Testing on the Toilet and post it in your office.

Permalink | Links to this post | 4 comments

3 days left for GTAC Proposals!

A brief reminder that there are only three days left to submit proposals for this year's Google Test Automation Conference. The proposal deadline is June 6th, after which the selection process will begin.

The Call For Proposals announcement is available at the Google Testing Blog here.

See you in October!
Lydia Ash
GTAC Conference Chair - 2008

Permalink | Links to this post | 0 comments