Testing Blog
GTAC: Call for Proposals & Attendance
Tuesday, December 11, 2012
By
Anthony Vallone
on behalf of the GTAC Committee
We are happy to announce that the application process is now open for presentation proposals and attendance for the seventh
GTAC
(Google Test Automation Conference) to be held at the
Google New York office
on April 23 - 24th, 2013.
GTAC brings together engineers from many organizations to discuss test automation. It is a great opportunity to present, learn, and challenge modern testing technologies and strategies. GTAC will be streamed live on YouTube this year, so even if you can’t attend, you’ll be able to watch the conference from your computer.
Speakers
Presentations are targeted at student, academic, and experienced engineers working on test automation. Full presentations and lightning talks are 45 minutes and 15 minutes respectively. Speakers should be prepared for a question and answer session following their presentation. As mentioned in our
recent post
, the main theme is on testing media and mobile, however, we will consider proposals on other topics.
Application
For presentation proposals and/or attendance, complete
this form
. We will be selecting about 200 applicants for the event.
Deadline
The due date for both presentation and attendance applications is Jan 23rd, 2013.
Fees
There are no registration fees. We will send out detailed registration instructions to each invited applicant. We will provide meals. Attendees must arrange their own travel and accommodations.
12 comments
Testacular - Spectacular Test Runner for JavaScript
Tuesday, November 27, 2012
By
Vojta Jína
[NOTE: After this post was published, Testacular was renamed
Karma
.]
“Testacular has changed my life. Now I test-drive everything.”
-- Matias Cudich, YouTube on TV team lead
At Google we believe in testing. On the
AngularJS
team, it’s even worse - we are super crazy about testing. Every feature of the framework is designed with testability in mind.
We found that we were struggling with existing tools, so we decided to write our own test runner. We wanted a test runner that would meet all of our needs for both quick development and continuous integration -- a truly spectacular test runner. We've called it
Testacular
.
Let's walk through some mental tests for what we believe makes for an ideal test runner...
it(‘should be fast’)
In order to be productive and creative you need instant feedback. Testacular watches the files in your application. Whenever you change any of them, it immediately executes the specified tests and reports the results. You never have to leave your text editor.
This enables a new way of developing. Instead of moving back and forth between the editor and the browser, you can simply stay in the editor and experiment. You instantly see the results at the command line whenever your changes are saved.
Besides that, our experience says that if test execution is slow, people don’t write tests. Testacular eliminates many barriers that keep folks from writing tests. When developers get instant feedback from their tests, the tests become an asset rather than annoyance.
it(‘should use real browsers’)
JavaScript itself is pretty consistent between different browsers, so one could potentially test browser code in non-browser environments like
Node.js
. Unfortunately, that’s not the case with the DOM APIs. AngularJS does a lot of DOM manipulation, and we need to be sure that it works across browsers. Executing tests on real browsers is a must.
And because Testacular communicates with browsers through a common protocols (eg. HTTP or WebSocket), you can test not only on desktop browsers but also on other devices such as mobile phones and tablets. For instance, the YouTube team uses Testacular to run continuous integration builds on PlayStation 3.
Another advantage of using real browsers is that you can use any of the tools that the browser provides. For example, you can jump into a debugger and step through your test.
it(‘should be reliable/stable’)
To be honest, most of these ideas were already implemented in
JsTD
almost three years ago. I think these are truly great ideas. Unfortunately, the implementation was flaky. It’s very easy to get JsTD into an inconsistent state, so you end up restarting it pretty much all day.
Testacular solves that. It can run for days, without restarting. That’s because every test run is executed in a fresh iframe. It reconnects browsers that have lost their connection to the server. And yep, it can gracefully recover from other issues, like syntax errors in the code under test.
We'd like to invite you to take Testacular for a spin. You can learn a bit more in this screencast. Please let us know what you think!
The project is open sourced and developed on
GitHub
.
10 comments
A Virtual Battlefield... with Bugs: Ship Wars @ Google Kirkland
Thursday, November 08, 2012
By Anthony F. Voellm (aka Tony the
@p3rfguy
/
G+
) and Emily Bedont
On Wednesday, October 24th, while sitting under the Solar System, 30 software engineers from the Greater Seattle area came together at
Google Kirkland
to partake in the first ever Test Edition of
Ship Wars
. Ship Wars was created by two
Google Waterloo
engineers, Garret Kelly and Aaron Kemp, as a 20% project. Yes, 20% time does exist at Google! The object of the game is to code a spaceship that will outperform all others in a virtual universe - algorithm vs algorithm.
The Kirkland event marked the 7th iteration of the program which was also recently done in NYC. Kirkland however was the first time that the game had been customized to encourage exploratory testing. In the case of "Ship Wars the
Test Edition
," we planted 4 bugs that the engineering participants were awarded for finding. Well, we ran out of prizes and were quickly reminded that when you put a lot of testing minded people in a room, many bugs will be unveiled! One of the best unveiled bugs was not one of the four planted in the simulator. When turning your ship 90 degrees, the ship actually turned -90 degrees. Oops!
Participants were encouraged to test their spaceship built on their own machine or a Google Chromebook. While the coding was done in the browser, the simulator and web server were run on
Google Compute Engine
. Throughout the 90 minutes, people challenged other participants to duels. Head-to-head battles took place on Chromebooks at the front of the room. There were many accolades called out but in the end, there could only be one champion who would walk away with a brand spankin’ new Nexus7. Check out our
video
of the evening’s activities.
Sounds fun, huh? We sure hope our participants, including our first place winner shown receiving the Nexus 7 from Garret, enjoyed the evening! Beyond the battles, our guests were introduced to the revived
Google Testing Blog
, heard firsthand that
GTAC
will be back in 2013, learned about testing at Google, and interacted with Googlers in a "Googley" environment. Achievement unlocked.
Special thanks to all the Googlers that supported the event!
1 comment
GTAC Coming to New York in the Spring
Tuesday, October 30, 2012
By
Anthony Vallone
on behalf of the GTAC Committee
The next and seventh
GTAC
(Google Test Automation Conference) will be held on April 23-24, 2013 at the beautiful
Google New York
office! We had a late start preparing for GTAC, but things are now falling into place. This will be the second time it is hosted at our second largest engineering office. We are also sticking with our tradition of changing the region each year, as the last GTAC was held in California.
The GTAC event brings together engineers from many organizations to discuss test automation. It is a great opportunity to present, learn, and challenge modern testing technologies and strategies. We will soon be recruiting speakers to discuss their innovations.
This year’s theme will be “Testing Media and Mobile“. In the past few years, substantial changes have taken place in both the media and mobile areas. Television is no longer the king of media. Over 27 billion videos are streamed in the U.S. per month. Over 1 billion people now own smartphones. HTML5 includes support for audio, video, and scalable vector graphics, which will liberate many web developers from their dependence on third-party media software. These are incredibly complex technologies to test. We are thrilled to be hosting this event in which many in the industry will share their innovations.
Registration information for speakers and attendees will soon be posted here and on the GTAC site (
https://developers.google.com/gtac
). Even though we will be focusing on “Testing Media and Mobile”, we will be accepting proposals for talks on other topics.
10 comments
Why Are There So Many C++ Testing Frameworks?
Friday, October 26, 2012
By Zhanyong Wan - Software Engineer
These days, it seems that everyone is rolling their own C++ testing framework, if they haven't done so already. Wikipedia has a
partial list
of such frameworks. This is interesting because many OOP languages have only one or two major frameworks. For example, most Java people seem happy with either
JUnit
or
TestNG
. Are C++ programmers the do-it-yourself kind?
When we started working on
Google Test
(Google’s C++ testing framework), and especially after we
open-sourced it
, people began asking us why we were doing it. The short answer is that we couldn’t find an existing C++ testing framework that satisfied all our needs. This doesn't mean that these frameworks were all poorly designed or implemented. Rather, many of them had great ideas and tricks that we learned from. However, Google had a huge number of C++ projects that got compiled on various operating systems (Linux, Windows, Mac OS X, and later Android, among others) with different compilers and all kinds of compiler flags, and we needed a framework that worked well in all these environments and ccould handle many different types and sizes of projects.
Unlike Java, which has the famous slogan "Write once, run anywhere," C++ code is being written in a much more diverse environment. Due to the complexity of the language and the need to do low-level tasks, compatibility between different C++ compilers and even different versions of the same compiler is poor. There is a C++ standard, but it's not well supported by compiler vendors. For many tasks you have to rely on unportable extensions or platform-specific functionality. This makes it hard to write a reasonably complex system that can be built using many different compilers and works on many platforms.
To make things more complicated, most C++ compilers allow you to turn off some standard language features in return for better performance. Don't like using exceptions? You can turn it off. Think dynamic cast is bad? You can disable
Run-Time Type Identification
, the feature behind dynamic cast and run-time access to type information. If you do any of these, however, code using these features will fail to compile. Many testing frameworks rely on exceptions. They are automatically out of the question for us since we turn off exceptions in many projects (in case you are curious, Google Test doesn’t require exceptions or run-time type identification by default; when these language features are turned on, Google Test will try to take advantage of them and provide you with more utilities, like the
exception assertions
.).
Why not just write a portable framework, then? Indeed, that's a top design goal for Google Test. And authors of some other frameworks have tried this too. However, this comes with a cost. Cross-platform C++ development requires much more effort: you need to test your code with different operating systems, different compilers, different versions of them, and different compiler flags (combine these factors and the task soon gets daunting); some platforms may not let you do certain things and you have to find a workaround there and guard the code with conditional compilation; different versions of compilers have different bugs and you may have to revise your code to bypass them all; etc. In the end, it's hard unless you are happy with a bare-bone system.
So, I think a
major reason that we have many C++ testing frameworks is that C++ is different in different environments, making it hard to write portable C++ code
. John's framework may not suit Bill's environment, even if it solves John's problems perfectly.
Another reason is that
some limitations of C++ make it impossible to implement certain features really well, and different people chose different ways to workaround the limitations
. One notable example is that C++ is a statically-typed language and doesn't support reflection. Most Java testing frameworks use reflection to automatically discover tests you've written such that you don't have to register them one-by-one. This is a good thing as manually registering tests is tedious and you can easily write a test and forget to register it. Since C++ has no reflection, we have to do it differently. Unfortunately there is no single best option. Some frameworks require you to register tests by hand, some use scripts to parse your source code to discover tests, and some use macros to automate the registration. We prefer the last approach and think it works for most people, but some disagree. Also, there are different ways to devise the macros and they involve different trade-offs, so the result is not clear cut.
Let’s see some actual code to understand how Google Test solves the test registration problem. The simplest way to add a test is to use the
TEST
macro (what else would we name it?):
TEST(
Subject, HasCertainProperty
) {
… testing code goes here …
}
This defines a test method whose purpose is to verify that the given subject has the given property. The macro automatically registers the test with Google Test such that it will be run when the test program (which may contain many such
TEST
definitions) is executed.
Here’s a more concrete example that verifies a Factorial() function works as expected for positive arguments:
TEST(FactorialTest, HandlesPositiveInput) {
EXPECT_EQ(1, Factorial(1));
EXPECT_EQ(2, Factorial(2));
EXPECT_EQ(6, Factorial(3));
EXPECT_EQ(40320, Factorial(8));
}
Finally,
many C++ testing framework authors neglected extensibility and were happy just providing canned solutions
, so we ended up with many solutions, each satisfying a different niche but none general enough. A versatile framework must have a good extension story. Let's face it: you cannot be all things to all people, no matter what. Instead of bloating the framework with rarely used features, we should provide good out-of-box solutions for maybe 95% of the use cases, and leave the rest to extensions. If I can easily extend a framework to solve a particular problem of mine, I will feel less motivated to write my own thing. Unfortunately, many framework authors don't seem to see the importance of extensibility. I think that mindset contributed to the plethora of frameworks we see today. In
Google Test
, we try to make it easy to expand your testing vocabulary by
defining custom assertions
that generate informative error messages. For instance, here’s a naive way to verify that an int value is in a given range:
bool IsInRange(int value, int low, int high) {
return low <= value && value <= high;
}
...
EXPECT_TRUE(IsInRange(SomeFunction(), low, high));
The problem is that when the assertion fails, you only know that the value returned by SomeFunction() is not in range [low, high], but you have no idea what that return value and the range actually are -- this makes debugging the test failure harder.
You
could
provide a custom message to make the failure more descriptive:
EXPECT_TRUE(IsInRange(SomeFunction(), low, high))
<<
"SomeFunction() = "
<< SomeFunction()
<<
", not in range ["
<< low <<
", "
<< high <<
"]"
;
Except that this is incorrect as
SomeFunction()
may
return a different answer each time. You can fix that by introducing an intermediate variable to hold the function’s result:
int result = SomeFunction();
EXPECT_TRUE(IsInRange(result, low, high))
<<
"result (return value of SomeFunction()) = "
<< result
<<
", not in range ["
<< low <<
", "
<< high <<
"]"
;
However this is tedious and obscures what you are really trying to do. It’s not a good pattern when you need to do the “is in range” check repeatedly. What we need here is a way to abstract this pattern into a reusable construct.
Google Test lets you define a test predicate like this:
AssertionResult IsInRange(int value, int low, int high) {
if (value < low)
return
AssertionFailure
()
<< value <<
" < lower bound "
<< low;
else if (value > high)
return
AssertionFailure
()
<< value <<
" > upper bound "
<< high;
else
return
AssertionSuccess
()
<< value <<
" is in range ["
<< low <<
", "
<< high <<
"]"
;
}
Then the statement
EXPECT_TRUE(IsInRange(SomeFunction(), low, high))
may print (assuming that
SomeFunction()
returns 13):
Value of: IsInRange(SomeFunction(), low, high)
Actual: false (13 < lower bound 20)
Expected: true
The same
IsInRange()
definition also lets you use it in an
EXPECT_FALSE
context, e.g.
EXPECT_FALSE(IsInRange(AnotherFunction(), low, high))
could print:
Value of: IsInRange(AnotherFunction(), low, high)
Actual: true (25 is in range [20, 60])
Expected: false
This way, you can build a library of test predicates for your problem domain, and benefit from clear, declarative test code and descriptive failure messages.
In the same vein,
Google Mock
(our C++ mocking framework) allows you to
easily define matchers
that can be used exactly the same way as built-in matchers. Also, we have included an
event listener API
in Google Test for people to write plug-ins. We hope that people will use these features to extend Google Test/Mock for their own need and contribute back extensions that might be generally useful.
Perhaps one day we will solve the C++ testing framework fragmentation problem, after all. :-)
3 comments
Hermetic Servers
Wednesday, October 03, 2012
By
Chaitali Narla
and
Diego Salas
Consider a complex and rich web app. Under the hood, it is probably a maze of servers, each performing a different task and most talking to each other. Any user action navigates this server maze on its round-trip from the user to the datastores and back. A lot of Google’s web apps are like this including
GMail
and
Google+
. So how do we write end-to-end tests for them?
The “End-To-End” Test
An end-to-end test in the Google testing world is a test that exercises the entire server stack from a user request to response. Here is a simplified view of the System Under Test (SUT) that an end-to-end test would assert. Note that the frontend server in the SUT connects to a third backend which this particular user request does not need.
One of the challenges to writing a
fast
and
reliable
end-to-end test for such a system is avoiding network access. Tests involving network access are slower than their counterparts that only access local resources, and accessing external servers might lead to
flakiness
due to lack of determinism or unavailability of the external servers.
Hermetic Servers
One of the tricks we use at Google to design end-to-end tests is
Hermetic Servers
.
What is a Hermetic Server? The short definition would be a “
server in a box
”. If you can start up the entire server on a single machine that has no network connection AND the server works as expected, you have a hermetic server! This is a special case of the more general “hermetic” concept which applies to an isolated system not necessarily on a single machine.
Why is it useful to have a hermetic server? Because if your entire SUT is composed of hermetic servers, it could all be started on a single machine for testing; no network connection necessary! The single machine could be a physical or virtual machine.
Designing Hermetic Servers
The process for building a hermetic server starts early in the design phase of any new server. Some things we watch out for:
All connections to other servers are injected into the server at runtime using a suitable form of
dependency injection
such as commandline flags or
Guice
.
All required static files are bundled in the server binary.
If the server talks to a datastore, make sure the datastore can be
faked
with data files or in-memory implementations.
Meeting the above requirements ensures we have a highly configurable server that has potential to become a hermetic server. But it is not yet ready to be used in tests. We do a few more things to complete the package:
Make sure those connection points which our test won’t exercise have appropriate
fakes
or mocks to verify this non-interaction.
Provide modules to easily populate datastores with test data.
Provide logging modules that can help trace the request/response path as it passes through the SUT.
Using Hermetic Servers in tests
Let’s take the SUT shown earlier and assume all the servers in it are hermetic servers. Here is how an end-to-end test for the same user request would look:
The end-to-end test does the following steps:
starts the entire SUT as shown in the diagram on a single machine
makes requests to the server via the test client
validates responses from the server
One thing to note here is the mock server connection for the backend is not needed in this test. If we wish to test a request that needs this backend, we would have to provide a hermetic server at that connection point as well.
This end-to-end test is more reliable because it uses no network connection. It is faster because everything it needs is available in-memory or in the local hard disk. We run such tests on our continuous builds, so they run at each changelist affecting any of the servers in the SUT. If the test fails, the logging module helps track where the failure occurred in the SUT.
We use hermetic servers in a lot of end-to-end tests. Some common cases include
Startup tests for servers using
Guice
to verify that there are no Guice errors on startup.
API tests for backend servers.
Micro-benchmark performance tests.
UI and API tests for frontend servers.
Conclusion
Hermetic servers do have some limitations. They will increase your test’s runtime since you have to start the entire SUT each time you run the end-to-end test. If your test runs with limited resources such as memory and CPU, hermetic servers might push your test over those limits as the server interactions grow in complexity. The dataset size you can use in the in-memory datastores will be much smaller than production datastores.
Hermetic servers are a great testing tool. Like all other tools, they need to be used thoughtfully where appropriate.
10 comments
Conversation with a Test Engineer
Wednesday, September 19, 2012
By Alan Myrvold
Alan Faulkner is a Google Test Engineer working on DoubleClick Bid Manager, which enables advertising agencies and advertisers to bid on multiple ad exchanges. Bid Manager is the next generation of the Invite Media product, acquired by Google in 2010. Alan Faulkner has been focused on the migration component of Bid Manager, which transitions advertiser information from Invite Media to Bid Manager. He joined Google in August 2011, and works in the Kirkland, WA office.
Are you a Test Engineer, or a Software Engineer in Test, and what’s the difference?
Right now, I’m a Test Engineer, but the two roles can be very similar. As a Test Engineer, you’re more focused on the overall quality of the product and speed of releases, while a Software Engineer in Test might focus more on test frameworks, automation, and refactoring code for testability. I think of the difference as more of a shift in focus and not capabilities, since both roles at Google need to be able to write production quality code. Example test engineering tasks I worked on are introducing an automated release process, identifying areas for the team to improve code coverage, and reducing the manual steps needed to validate data correctness.
What is a typical day for you?
When I get in, I look at any code reviews I need to respond to, look for any production bugs from technical account managers that are high priority, and then start writing code. In my current role, I focus my development effort on improving the efficiency and coverage of our large scale integration tests and frameworks. I also work on adding additional features to our product that improve our testability. I typically spend anywhere from 50% to 75% of my time either writing code or participating in code reviews.
Do you write only test code?
No, I write a lot of code that is included in the product as well. One of the great things about being an SET or TE at Google is that you can write product code as easily as test code. I write both. My test code focuses on improving test frameworks and enabling developers to write integration tests. The production code that I write focuses on increasing the verification of external inputs. I also focus on adding features that improve testability. This pushes more quality features into the product itself rather than relying on test code for correctness.
What programming languages do you use?
Both the test and product code are mostly Java. Occasionally I use Python or C++ too.
How much time to do you spend doing manual testing?
Right now, with the role I am in, I spend less than 5% of my time doing manual testing. Although some exploratory testing helps develop product knowledge and find risky areas, it doesn’t scale as a repeated process. There are a small amount of manual steps and I focus on ways to help reduce this so our team does not spend our time doing repeated manual steps as part of our data migration.
Do you write unit tests for code that isn’t yours?
At Google, the responsibility of testing is shared across all product engineers, not just Test Engineers. Everyone is responsible for writing unit tests as well as integration tests for their components. That being said, I have written unit tests for components that are outside of what I developed but that has been to illustrate how to write a unit test for said component. This component usually involved a abnormally complex set of code or to illustrate using a new mocking framework, such as
Mockito
.
What do you like about working on the Google advertising products?
I like the challenges of the scalability problems we need to solve, from handling massive amounts of data to dealing with lots of real time ad requests that need to be responded to in milliseconds. I also like the impact, since the products affect a lot of people. It’s rewarding to work on stuff like that.
How is testing at Google different from your experience at other companies?
I feel the role is more flexible at Google. There are fewer SET’s and TE’s in my group at Google per developer, and you have the flexibility to pick what is most important. For example, I get to write a lot of production code to fix bugs, make the code more testable, and increasing the visibility into errors encountered during our data migrations. Plus, developers at Google spend a lot of time writing tests, so testing isn’t just my responsibility.
How does the Google Kirkland office differ from the headquarters in Mountain View?
What I really like about the offices at Google is that each of them has their own local feel and personality. Google encourages this! For instance, the office here in Kirkland has a climbing wall, boats and all the conference rooms in our building are named after local bands in the area. The office in Seattle has kayaks and the New York office has an actual food truck in its cafeteria.
What’s the future of testing at Google?
I think the future is really bright. We have a lot of flexibility to make a big impact on quality, testability and improving our release velocity. We need to release new features faster and with good quality. The problems that we face are complex and at an extreme scale. We need engineering teams focused on ensuring that we have efficient ways to simulate and test. There will always be a need for testers and developers that focus on these areas here at Google.
Interested in
test jobs at Google
?
5 comments
Testing 2.0
Thursday, August 30, 2012
By Anthony F. Voellm (aka Tony the perfguy)
It’s amazing what has happened in the field of test in the last 20 years... a lot of “art” has turned into “science”. Computer scientists, engineers, and many other disciplines have worked on
provable systems and calculus
,
pioneered model based testing
, invented
security fuzz testing
, and even settled on a common pattern for unit tests called
xunit
. The xunit pattern shows up in open source software like JUnit as well as in Microsoft development
test tools
.
With all this innovation in test, there’s no wonder
test is dead
. The situation is no different from the late 1800’s when
patents were declared dead
. Everything had been invented. So now that everything in test has been invented, it’s dead.
Well... if you believe everything in test has been invented then please stop reading now :)
As an aside: “
Test is dead
” was a keynote at the Google Test Automation Conference (GTAC) in 2011. You can watch that talk and many other GTAC test talks on YouTube, and I definitely recommend you check them out
here
. Talks span a wide range of topics ranging from
GUI Automation
to
Cloud
.
What really excites me these days is that we have closed a chapter on test. A lot of the foundation of writing and testing great software has been laid (examples at the beginning of the post, tools like Webdriver for UI, FIO for storage, and much more), which I think of as Testing 1.0. We all use Testing 1.0 day in and day out. In fact at Google, most of the developers (called Software Engineers or SWEs) do the basic Testing 1.0 work and we have a high bar on quality.
Knuth
once said "Be careful about using the following code -- I've only proven that it works, I haven't tested it."
This brings us to the current chapter in test which I call Testing 1.5. This chapter is being written by computer scientists, applied scientists, engineers, developers, statisticians, and many other disciplines. These people come together in the Software Engineer in Test (
SET
) and Test Engineer (TE) roles at Google. SET/TEs focus on; developing software faster, building it better the first time, testing it in depth, releasing it quicker, and making sure it works in all environments. We often put deep test focus on Security, Reliability and Performance. I sometimes think of the SET/TE’s as risk assessors whose role is to figure out the probability of finding a bug, and then working to reduce that probability. Super interesting computer science problems where we take a solid engineering approach, rather than a process oriented / manual / people intensive based approach. We always look to scale with machines wherever possible.
While Testing 1.0 is done and 1.5 is alive and well, it’s Testing 2.0 that gets me up early in the morning to start my day. Imagine if we could reinvent how we use and think about tests. What if we could automate the complex decisions on good and bad quality that humans are still so good at today? What would it look like if we had a system collecting all the “quality signals” (think: tests, production information, developer behavior, …) and could predict how good the code is today, and what it most likely will be tomorrow? That would be so awesome...
Google is working on Testing 2.0 and we’ll continue to contribute to Testing 1.0 and 1.5. Nothing is static... keep up or miss an amazing
ride
.
Peace.... Tony
Special thanks to Chris, Simon, Anthony, Matt, Asim, Ari, Baran, Jim, Chaitali, Rob, Emily, Kristen, Annie, and many others for providing input and suggestions for this post.
4 comments
Testing Google's New API Infrastructure
Monday, August 20, 2012
By
Anthony Vallone
If you haven’t noticed, Google has been launching
many public APIs
recently. These APIs are empowering mobile app, desktop app, web service, and website developers by providing easy access to Google tools, services, and data. In the past couple of years, we have invested heavily in building a new API infrastructure for our APIs. Before this infrastructure, our teams had numerous technical challenges to solve when releasing an API: scalability, authorization, quota, caching, billing, client libraries, translation from external REST requests to internal RPCs, etc. The new infrastructure generically solves these problems and allows our teams to focus on their service. Automating testing of these new APIs turned out to be quite a large problem. Our solution to this problem is somewhat unique within Google, and we hope you find it interesting.
System Under Test (SUT)
Let’s start with a simplified view of the SUT design:
A developer’s application uses a Google-supplied API Client Library to call Google API methods. The library connects to the API Infrastructure service and sends the request. Part of the request defines the particular API and version being used by the client. This service is knowledgeable of all Google APIs, because they are defined by API Configuration files. These files are created by each API providing team. Configuration files declare API versions, methods, method parameters, and other API settings. Given an API request and information about the API, the API Infrastructure Service can translate the request to Google’s internal RPC format and pass it to the correct API Provider Service. This service then satisfies the request and passes the response back to the developer’s app via the API Infrastructure Service and API Client Library.
Now, the Fun Part
As of this writing, we have released 10
language-specific client libraries
and 35 public APIs built on this infrastructure. Also, each of the libraries need to work on multiple platforms. Our test space has three dimensions: API (35), language (10), and platform (varies by lib). How are we going to test all the libraries on all the platforms against all the APIs when we only have two engineers on the team dedicated to test automation?
Step 1: Create a Comprehensive API
Each API uses different features of the infrastructure, and we want to ensure that every feature works. Rather than use the APIs to test our infrastructure, we create a Test API that uses every feature. In some cases where API configuration options are mutually exclusive, we have to create API versions that are feature-specific. Of course, each API team still needs to do basic integration testing with the infrastructure, but they can assume that the infrastructure features that their API depends on are well tested by the infrastructure team.
Step 2: Client Abstraction Layer in the Tests
We want to avoid creating library-specific tests, because this would lead to mass duplication of test logic. The obvious solution is to create a test library to be used by all tests as an abstraction layer hiding the various libraries and platforms. This allows us to define tests that don’t care about library or platform.
Step 3: Adapter Servers
When a test library makes an API call, it should be able to use any language and platform. We can solve this by setting up servers on each of our target platforms. For each target language, create a language-specific server. These servers receive requests from test clients. The servers need only translate test client requests into actual library calls and return the response to the caller. The code for these servers is quite simple to create and maintain.
Step 4: Iterate
Now, we have all the pieces in place. When we run our tests, they are configured to run over all supported languages and platforms against the test API:
Test Nirvana Achieved
We have a suite of straightforward tests that focus on infrastructure features. When the tests run, they are quick, reliable, and test all of our supported features, platforms, and libraries. When a feature is added to the API infrastructure, we only need to create one new test, update each adapter server to handle a new call type, and add the feature to the Test API.
11 comments
Covering all your codebases: A conversation with a Software Engineer in Test
Saturday, August 11, 2012
Cross-posted from the
Google Student Blog
Today we’re featuring Sabrina Williams, a Software Engineer in Test who joined Google in August 2011. Software Engineers in Test undertake a broad range of challenges on a daily basis, designing and building intelligent systems that can explore various use cases and scenarios for distributed computing infrastructure. Read on to learn more about Sabrina’s path to Google and what she works on now that she’s here!
Tell us about yourself and how you got to Google.
I grew up in rural Prunedale, Calif. and went to Stanford where I double-majored in philosophy and computer science. After college I spent six years as a software engineer at HP, working primarily on printer drivers. I began focusing on testing my last two years there—reading books, looking up information and prototyping test tools in my own time. By the time I left, I’d started a project for an automated test framework that most of our lab used.
I applied for a software engineering role at Google four years ago and didn’t do well in my interviews. Thankfully, a Google recruiter called last year and set me up for software engineer (SWE) interviews again. After a day of talking about testing and mocking for every design question I answered, I was told that there were opportunities for me in SWE and SET. I ended up choosing the SET role after speaking with the SET hiring manager. He said two things that convinced me. First, SETs spend as much time coding as SWEs, and I wanted a role where I could write code. Second, the SETs job is to creatively solve testing problems, which sounded more interesting to me than writing features for a product. This seemed like a really unique and appealing opportunity, so I took it!
So what exactly do SETs do?
SETs are SWEs who are really into testing. We help SWEs design and refactor their code so that it is more testable. We work with test engineers (TEs) to figure out how to automate difficult test cases. We also write harnesses, frameworks and tools to make test automation possible. SETs tend to have the best understanding of how everything plays together (production code, manual tests, automated tests, tools, etc.) and we have to make that information accessible to everyone on the team.
What project do you work on?
I work on the
Google Cloud Print
team. Our goal is to make it possible to print anywhere from any device. You can use Google Cloud Print to connect home and work printers to the web so that you (and anyone you share your printers with) can access them from your phone, tablet, Chromebook, PC or any other supported web-connected device.
What advice would you give to aspiring SETs?
First, for computer science majors in general: if there’s any other field about which you are passionate, at least minor in it. CS is wonderfully chameleonic in that it can be applied to anything. So if, for example, you love art history, minor in art and you can write software to help restore images of old paintings.
For aspiring SETs, challenge yourself to write tests for all of the code you write for school. If you can get an internship where you have access to a real-world code base, study how that company approaches testing their code. If it’s well-tested, see how they did it. If it’s not well-tested, think about how you would test it. I don’t (personally) know of a CS program that has even a full course based on testing, so you’ll have to teach yourself. Start by looking up buzzwords like “unit test” and “test-driven development.” Look up the different types of tests (unit, integration, component, system, etc.). Find a code coverage tool (if a free/cheap one is available for your language of choice) and see how well you’re covering your code with your tests. Write a tool that will run all of your tests every time you build your code. If all of this sounds like fun...well...we need more people like you!
If you’re interested in applying for a Software Engineer in Test position, please apply for our general
Software Engineer
position, then indicate in your resume objective line that you’re interested in the SET role.
Posted by Jessica Safir, University Programs
2 comments
Welcome to the Next Generation of Google Testing
Saturday, August 04, 2012
By
Anthony Vallone
Wow... it has been a long time since we’ve posted to the blog. This past year has been a whirlwind of change for many test teams as Google has restructured leadership with a focus on products. Now that the dust has settled, our teams are leaner, more focused, and more effective. We have learned quite a bit over the past year about how best to tackle and manage test problems at monumental scale. The next generation of test teams at Google are looking forward to sharing all that we have learned. Stay tuned for a revived Google Testing Blog that will provide deep insight into our latest testing technologies and strategies.
12 comments
Labels
TotT
102
GTAC
61
James Whittaker
42
Misko Hevery
32
Code Health
30
Anthony Vallone
27
Patrick Copeland
23
Jobs
18
Andrew Trenk
13
C++
11
Patrik Höglund
8
JavaScript
7
Allen Hutchison
6
George Pirocanac
6
Zhanyong Wan
6
Harry Robinson
5
Java
5
Julian Harty
5
Adam Bender
4
Alberto Savoia
4
Ben Yu
4
Erik Kuefler
4
Philip Zembrod
4
Shyam Seshadri
4
Chrome
3
Dillon Bly
3
John Thomas
3
Lesley Katzen
3
Marc Kaplan
3
Markus Clermont
3
Max Kanat-Alexander
3
Sonal Shah
3
APIs
2
Abhishek Arya
2
Alan Myrvold
2
Alek Icev
2
Android
2
April Fools
2
Chaitali Narla
2
Chris Lewis
2
Chrome OS
2
Diego Salas
2
Dori Reuveni
2
Jason Arbon
2
Jochen Wuttke
2
Kostya Serebryany
2
Marc Eaddy
2
Marko Ivanković
2
Mobile
2
Oliver Chang
2
Simon Stewart
2
Stefan Kennedy
2
Test Flakiness
2
Titus Winters
2
Tony Voellm
2
WebRTC
2
Yiming Sun
2
Yvette Nameth
2
Zuri Kemp
2
Aaron Jacobs
1
Adam Porter
1
Adam Raider
1
Adel Saoud
1
Alan Faulkner
1
Alex Eagle
1
Amy Fu
1
Anantha Keesara
1
Antoine Picard
1
App Engine
1
Ari Shamash
1
Arif Sukoco
1
Benjamin Pick
1
Bob Nystrom
1
Bruce Leban
1
Carlos Arguelles
1
Carlos Israel Ortiz García
1
Cathal Weakliam
1
Christopher Semturs
1
Clay Murphy
1
Dagang Wei
1
Dan Maksimovich
1
Dan Shi
1
Dan Willemsen
1
Dave Chen
1
Dave Gladfelter
1
David Bendory
1
David Mandelberg
1
Derek Snyder
1
Diego Cavalcanti
1
Dmitry Vyukov
1
Eduardo Bravo Ortiz
1
Ekaterina Kamenskaya
1
Elliott Karpilovsky
1
Elliotte Rusty Harold
1
Espresso
1
Felipe Sodré
1
Francois Aube
1
Gene Volovich
1
Google+
1
Goran Petrovic
1
Goranka Bjedov
1
Hank Duan
1
Havard Rast Blok
1
Hongfei Ding
1
Jason Elbaum
1
Jason Huggins
1
Jay Han
1
Jeff Hoy
1
Jeff Listfield
1
Jessica Tomechak
1
Jim Reardon
1
Joe Allan Muharsky
1
Joel Hynoski
1
John Micco
1
John Penix
1
Jonathan Rockway
1
Jonathan Velasquez
1
Josh Armour
1
Julie Ralph
1
Kai Kent
1
Kanu Tewary
1
Karin Lundberg
1
Kaue Silveira
1
Kevin Bourrillion
1
Kevin Graney
1
Kirkland
1
Kurt Alfred Kluever
1
Manjusha Parvathaneni
1
Marek Kiszkis
1
Marius Latinis
1
Mark Ivey
1
Mark Manley
1
Mark Striebeck
1
Matt Lowrie
1
Meredith Whittaker
1
Michael Bachman
1
Michael Klepikov
1
Mike Aizatsky
1
Mike Wacker
1
Mona El Mahdy
1
Noel Yap
1
Palak Bansal
1
Patricia Legaspi
1
Per Jacobsson
1
Peter Arrenbrecht
1
Peter Spragins
1
Phil Norman
1
Phil Rollet
1
Pooja Gupta
1
Project Showcase
1
Radoslav Vasilev
1
Rajat Dewan
1
Rajat Jain
1
Rich Martin
1
Richard Bustamante
1
Roshan Sembacuttiaratchy
1
Ruslan Khamitov
1
Sam Lee
1
Sean Jordan
1
Sharon Zhou
1
Shiva Garg
1
Siddartha Janga
1
Simran Basi
1
Stan Chan
1
Stephen Ng
1
Tejas Shah
1
Test Analytics
1
Test Engineer
1
Tim Lyakhovetskiy
1
Tom O'Neill
1
Vojta Jína
1
automation
1
dead code
1
iOS
1
mutation testing
1
Archive
►
2024
(13)
►
Dec
(1)
►
Oct
(1)
►
Sep
(1)
►
Aug
(1)
►
Jul
(1)
►
May
(3)
►
Apr
(3)
►
Mar
(1)
►
Feb
(1)
►
2023
(14)
►
Dec
(2)
►
Nov
(2)
►
Oct
(5)
►
Sep
(3)
►
Aug
(1)
►
Apr
(1)
►
2022
(2)
►
Feb
(2)
►
2021
(3)
►
Jun
(1)
►
Apr
(1)
►
Mar
(1)
►
2020
(8)
►
Dec
(2)
►
Nov
(1)
►
Oct
(1)
►
Aug
(2)
►
Jul
(1)
►
May
(1)
►
2019
(4)
►
Dec
(1)
►
Nov
(1)
►
Jul
(1)
►
Jan
(1)
►
2018
(7)
►
Nov
(1)
►
Sep
(1)
►
Jul
(1)
►
Jun
(2)
►
May
(1)
►
Feb
(1)
►
2017
(17)
►
Dec
(1)
►
Nov
(1)
►
Oct
(1)
►
Sep
(1)
►
Aug
(1)
►
Jul
(2)
►
Jun
(2)
►
May
(3)
►
Apr
(2)
►
Feb
(1)
►
Jan
(2)
►
2016
(15)
►
Dec
(1)
►
Nov
(2)
►
Oct
(1)
►
Sep
(2)
►
Aug
(1)
►
Jun
(2)
►
May
(3)
►
Apr
(1)
►
Mar
(1)
►
Feb
(1)
►
2015
(14)
►
Dec
(1)
►
Nov
(1)
►
Oct
(2)
►
Aug
(1)
►
Jun
(1)
►
May
(2)
►
Apr
(2)
►
Mar
(1)
►
Feb
(1)
►
Jan
(2)
►
2014
(24)
►
Dec
(2)
►
Nov
(1)
►
Oct
(2)
►
Sep
(2)
►
Aug
(2)
►
Jul
(3)
►
Jun
(3)
►
May
(2)
►
Apr
(2)
►
Mar
(2)
►
Feb
(1)
►
Jan
(2)
►
2013
(16)
►
Dec
(1)
►
Nov
(1)
►
Oct
(1)
►
Aug
(2)
►
Jul
(1)
►
Jun
(2)
►
May
(2)
►
Apr
(2)
►
Mar
(2)
►
Jan
(2)
▼
2012
(11)
▼
Dec
(1)
GTAC: Call for Proposals & Attendance
►
Nov
(2)
Testacular - Spectacular Test Runner for JavaScript
A Virtual Battlefield... with Bugs: Ship Wars @ Go...
►
Oct
(3)
GTAC Coming to New York in the Spring
Why Are There So Many C++ Testing Frameworks?
Hermetic Servers
►
Sep
(1)
Conversation with a Test Engineer
►
Aug
(4)
Testing 2.0
Testing Google's New API Infrastructure
Covering all your codebases: A conversation with a...
Welcome to the Next Generation of Google Testing
►
2011
(39)
►
Nov
(2)
►
Oct
(5)
►
Sep
(2)
►
Aug
(4)
►
Jul
(2)
►
Jun
(5)
►
May
(4)
►
Apr
(3)
►
Mar
(4)
►
Feb
(5)
►
Jan
(3)
►
2010
(37)
►
Dec
(3)
►
Nov
(3)
►
Oct
(4)
►
Sep
(8)
►
Aug
(3)
►
Jul
(3)
►
Jun
(2)
►
May
(2)
►
Apr
(3)
►
Mar
(3)
►
Feb
(2)
►
Jan
(1)
►
2009
(54)
►
Dec
(3)
►
Nov
(2)
►
Oct
(3)
►
Sep
(5)
►
Aug
(4)
►
Jul
(15)
►
Jun
(8)
►
May
(3)
►
Apr
(2)
►
Feb
(5)
►
Jan
(4)
►
2008
(75)
►
Dec
(6)
►
Nov
(8)
►
Oct
(9)
►
Sep
(8)
►
Aug
(9)
►
Jul
(9)
►
Jun
(6)
►
May
(6)
►
Apr
(4)
►
Mar
(4)
►
Feb
(4)
►
Jan
(2)
►
2007
(41)
►
Oct
(6)
►
Sep
(5)
►
Aug
(3)
►
Jul
(2)
►
Jun
(2)
►
May
(2)
►
Apr
(7)
►
Mar
(5)
►
Feb
(5)
►
Jan
(4)
Feed
Follow @googletesting