<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Google Data &#187; Google Testing</title>
	<atom:link href="/category/google-testing/feed/" rel="self" type="application/rss+xml" />
	<link>https://googledata.org</link>
	<description>Everything Google: News, Products, Services, Content, Culture</description>
	<lastBuildDate>Wed, 28 Dec 2016 21:09:26 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=4.1.13</generator>
	<item>
		<title>Announcing OSS-Fuzz: Continuous Fuzzing for Open Source Software</title>
		<link>https://googledata.org/google-testing/announcing-oss-fuzz-continuous-fuzzing-for-open-source-software/</link>
		<comments>https://googledata.org/google-testing/announcing-oss-fuzz-continuous-fuzzing-for-open-source-software/#comments</comments>
		<pubDate>Thu, 01 Dec 2016 17:00:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=2adc4c02abbc29fb54b13b6c200c7f69</guid>
		<description><![CDATA[By Mike Aizatsky, Kostya Serebryany (Software Engineers, Dynamic Tools); Oliver Chang, Abhishek Arya (Security Engineers, Google Chrome); and Meredith Whittaker (Open Research Lead).&#160;We are happy to announce OSS-Fuzz, a new Beta program developed ...]]></description>
				<content:encoded><![CDATA[<i>By Mike Aizatsky, Kostya Serebryany (Software Engineers, Dynamic Tools); Oliver Chang, Abhishek Arya (Security Engineers, Google Chrome); and Meredith Whittaker (Open Research Lead).&nbsp;</i><br /><br /><strong>We are happy to announce <a href="https://github.com/google/oss-fuzz">OSS-Fuzz</a>, a new Beta program developed over the past years with the <a href="https://www.coreinfrastructure.org/">Core Infrastructure Initiative community</a>. This program will provide continuous fuzzing for select core open source software.</strong><br /><strong><br /></strong>Open source software is the backbone of the many apps, sites, services, and networked things that make up "the internet." It is important that the open source foundation be stable, secure, and reliable, as cracks and weaknesses impact all who build on it. <br /><br /><a href="https://en.wikipedia.org/wiki/Heartbleed">Recent</a> <a href="https://en.wikipedia.org/wiki/Stagefright_(bug)">security</a> <a href="https://googlechromereleases.blogspot.com/2016/09/stable-channel-updates-for-chrome-os.html">stories</a>confirm that errors like<a href="https://en.wikipedia.org/wiki/Buffer_overflow">buffer overflow</a> and<a href="https://en.wikipedia.org/wiki/Dangling_pointer">use-after-free</a> can have serious, widespread consequences when they occur in critical open source software. These errors are not only serious, but notoriously difficult to find via routine code audits, even for experienced developers. That's where<a href="https://en.wikipedia.org/wiki/Fuzz_testing">fuzz testing</a> comes in. By generating random inputs to a given program, fuzzing triggers and helps uncover errors quickly and thoroughly. <br /><br />In recent years, several efficient general purpose fuzzing engines have been implemented (e.g. <a href="http://lcamtuf.coredump.cx/afl/">AFL</a> and <a href="http://libfuzzer.info/">libFuzzer</a>), and we use them to <a href="https://security.googleblog.com/2016/08/guided-in-process-fuzzing-of-chrome.html">fuzz various components of the Chrome browser</a>. These fuzzers, when combined with <a href="https://github.com/google/sanitizers">Sanitizers</a>, can help find security vulnerabilities (e.g. buffer overflows, use-after-free, bad casts, integer overflows, etc), stability bugs (e.g. null dereferences, memory leaks, out-of-memory, assertion failures, etc) and <a href="https://blog.fuzzing-project.org/31-Fuzzing-Math-miscalculations-in-OpenSSLs-BN_mod_exp-CVE-2015-3193.html">sometimes</a>even logical bugs. <br /><br />OSS-Fuzz's goal is to make common software infrastructure more secure and stable by combining modern fuzzing techniques with scalable distributed execution. OSS-Fuzz combines various fuzzing engines (initially, libFuzzer) with Sanitizers (initially, <a href="http://clang.llvm.org/docs/AddressSanitizer.html">AddressSanitizer</a>) and provides a massive distributed execution environment powered by <a href="https://github.com/google/oss-fuzz/blob/master/docs/clusterfuzz.md">ClusterFuzz</a>. <br /><h2>Early successes</h2>Our initial trials with OSS-Fuzz have had good results. An example is the <a href="https://www.freetype.org/">FreeType</a> library, which is used on over a <a href="https://en.wikipedia.org/wiki/FreeType#Users">billion devices</a> to display text (and which might even be rendering the characters you are reading now). It is important for FreeType to be stable and secure in an age when fonts are loaded over the Internet. Werner Lemberg, one of the FreeType developers, <a href="https://savannah.nongnu.org/search/?type_of_search=bugs&amp;words=LibFuzzer&amp;offset=0&amp;max_rows=100#results">was</a>an early adopter of OSS-Fuzz. Recently the <a href="http://git.savannah.gnu.org/cgit/freetype/freetype2.git/tree/src/tools/ftfuzzer/ftfuzzer.cc">FreeType fuzzer</a> found a <a href="https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=53">new heap buffer overflow</a> only a few hours after the source change: <br /><br /><pre class="prettyprint">ERROR: AddressSanitizer: heap-buffer-overflow on address 0x615000000ffa <br />READ of size 2 at 0x615000000ffa thread T0<br />SCARINESS: 24 (2-byte-read-heap-buffer-overflow-far-from-bounds)<br />   #0 0x885e06 in tt_face_vary_cvtsrc/truetype/ttgxvar.c:1556:31<br /></pre><br />OSS-Fuzz automatically<a href="https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=53"> notified</a>the maintainer, who<a href="http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=7eeaf986b5ebb43cbbc8368c6e528ac311d87805">fixed</a> the bug; then OSS-Fuzz automatically<a href="https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=53#c3">confirmed</a> the fix. All in one day! You can see the <a href="https://bugs.chromium.org/p/oss-fuzz/issues/list?can=1&amp;q=type=Bug-Security,Bug%20-component:Infra%20status:Fixed,Verified&amp;sort=-id&amp;colspec=ID%20Type%20Component%20Status%20Library%20Reported%20Owner%20Summary">full list</a> of fixed and disclosed bugs found by OSS-Fuzz so far. <br /><h2>Contributions and feedback are welcome</h2>OSS-Fuzz has already found <strong><a href="https://bugs.chromium.org/p/oss-fuzz/issues/list?can=1&amp;q=-component%3AInfra+-status%3ADuplicate%2CWontFix&amp;sort=-id&amp;colspec=ID+Type+Component+Status+Library+Reported+Owner+Summary&amp;cells=ids">150 bugs</a></strong> in several widely used open source <a href="https://github.com/google/oss-fuzz/tree/master/projects">projects</a> (and churns <strong>~4 trillion test cases</strong> a week). With your help, we can make fuzzing a standard part of open source development, and work with the broader community of developers and security testers to ensure that bugs in critical open source applications, libraries, and APIs are discovered and fixed. We believe that this approach to automated security testing will result in real improvements to the security and stability of open source software. <br /><br />OSS-Fuzz is launching in Beta right now, and will be accepting suggestions for candidate open source projects. In order for a project to be accepted to OSS-Fuzz, it needs to have a large user base and/or be critical to Global IT infrastructure, a general heuristic that we are intentionally leaving open to interpretation at this early stage. See more details and instructions on how to apply <a href="https://github.com/google/oss-fuzz#accepting-new-projects">here</a>. <br /><br />Once a project is signed up for OSS-Fuzz, it is automatically subject to the 90-day disclosure deadline for newly reported bugs in our <a href="https://bugs.chromium.org/p/oss-fuzz/issues/list">tracker</a> (see details <a href="https://github.com/google/oss-fuzz#bug-disclosure-guidelines">here</a>). This matches industry's <a href="https://googleprojectzero.blogspot.com/2015/02/feedback-and-data-driven-updates-to.html">best practices</a> and improves end-user security and stability by getting patches to users faster. <br /><br />Help us ensure this program is truly serving the open source community and the internet which relies on this critical software, contribute and leave your feedback on <a href="https://github.com/google/oss-fuzz">GitHub</a>.]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/announcing-oss-fuzz-continuous-fuzzing-for-open-source-software/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>What Test Engineers do at Google: Building Test Infrastructure</title>
		<link>https://googledata.org/google-testing/what-test-engineers-do-at-google-building-test-infrastructure/</link>
		<comments>https://googledata.org/google-testing/what-test-engineers-do-at-google-building-test-infrastructure/#comments</comments>
		<pubDate>Fri, 18 Nov 2016 17:10:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=f4768eca0908ce57ccca3c4ff68ffcbf</guid>
		<description><![CDATA[Author: Jochen WuttkeIn a recent post, we broadly talked about What Test Engineers do at Google. In this post, I talk about one aspect of the work TEs may do: building and improving test infrastructure to make engineers more productive. Refurbishing le...]]></description>
				<content:encoded><![CDATA[<i>Author: Jochen Wuttke</i><br /><br />In a recent post, we broadly talked about <a href="https://testing.googleblog.com/2016/09/what-test-engineers-do-at-google.html">What Test Engineers do at Google</a>. In this post, I talk about one aspect of the work TEs may do: building and improving test infrastructure to make engineers more productive. <br /><br /><strong>Refurbishing legacy systems makes new tools necessary</strong><br />A few years ago, I joined an engineering team that was working on replacing a legacy system with a new implementation. Because building the replacement would take several years, we had to keep the legacy system operational and even add features, while building the replacement so there would be no impact on our external users. <br /><br />The legacy system was so complex and brittle that the engineers spent most of their time triaging and fixing bugs and <a href="https://testing.googleblog.com/2016/05/flaky-tests-at-google-and-how-we.html">flaky tests</a>, but had little time to implement new features. The goal for the rewrite was to learn from the legacy system and to build something that was easier to maintain and extend. As the team's TE, my job was to understand what caused the high maintenance cost and how to improve on it. I found two main causes: <br /><ul><li>Tight coupling and insufficient abstraction made unit testing very hard, and as a consequence, a lot of end-to-end tests served as functional tests of that code. </li><li>The infrastructure used for the end-to-end tests had no good way to create and inject fakes or mocks for these services.  As a result, the tests had to run the large number of servers for all these external dependencies. This led to very large and brittle tests that our <a href="https://testing.googleblog.com/2011/06/testing-at-speed-and-scale-of-google.html">existing test execution infrastructure</a> was not able to handle reliably.</li></ul><strong>Exploring solutions</strong><br />At first, I explored if I could split the large tests into smaller ones that would test specific functionality and depend on fewer external services. This proved impossible, because of the poorly structured legacy code. Making this approach work would have required refactoring the entire system and its dependencies, not just the parts my team owned. <br /><br />In my second approach, I also focussed on large tests and tried to mock services that were not required for the functionality under test. This also proved very difficult, because dependencies changed often and individual dependencies were hard to trace in a graph of over 200 services. Ultimately, this approach just shifted the required effort from maintaining test code to maintaining test dependencies and mocks. <br /><br />My third and final approach, illustrated in the figure below, made small tests more powerful. In the typical end-to-end test we faced, the client made <strong><a href="https://en.wikipedia.org/wiki/Remote_procedure_call">RPC</a>calls</strong> to several services, which in turn made RPC calls to other services. Together the client and the transitive closure over all backend services formed a large <a href="https://en.wikipedia.org/wiki/Graph_(discrete_mathematics)">graph</a> (not <a href="https://en.wikipedia.org/wiki/Tree_(graph_theory)">tree</a>!) of dependencies, which all had to be up and running for the end-to-end test. The new model changes how we test client and service integration. Instead of running the client on inputs that will somehow trigger RPC calls, we write unit tests for the code making <strong>method calls</strong> to the RPC stub. The stub itself is mocked with a common mocking framework like Mockito in Java. For each such test, a second test verifies that the data used to drive that mock "makes sense" to the actual service. This is also done with a unit test, where a replay client uses the same data the RPC mock uses to call the RPC handler method of the service. <br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://2.bp.blogspot.com/-XV6lUxNAMgs/WC81WN0TtHI/AAAAAAAAAQA/MBWOlMRo73MhXNfDF4E6LkPy7YuukVEXwCLcB/s1600/img1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="296" src="https://2.bp.blogspot.com/-XV6lUxNAMgs/WC81WN0TtHI/AAAAAAAAAQA/MBWOlMRo73MhXNfDF4E6LkPy7YuukVEXwCLcB/s640/img1.png" width="640" /></a></div><br />This pattern of integration testing applies to any RPC call, so the RPC calls made by a backend server to another backend can be tested just as well as front-end client calls. When we apply this approach consistently, we benefit from smaller tests that still test correct integration behavior, and make sure that the behavior we are testing is "real". <br /><br />To arrive at this solution, I had to build, evaluate, and discard several prototypes. While it took a day to build a proof-of-concept for this approach, it took me and another engineer a year to implement a finished tool developers could use. <br /><br /><strong>Adoption</strong><br />The engineers embraced the new solution very quickly when they saw that the new framework removes large amounts of boilerplate code from their tests. To further drive its adoption, I organized multi-day events with the engineering team where we focussed on migrating test cases. It took a few months to migrate all existing unit tests to the new framework, close gaps in coverage, and create the new tests that validate the mocks. Once we converted about 80% of the tests, we started comparing the efficacy of the new tests and the existing end-to-end tests. <br /><br />The results are very good: <br /><ul><li>The new tests are as effective in finding bugs as the end-to-end tests are. </li><li>The new tests run in about 3 minutes instead of 30 minutes for the end-to-end tests. </li><li>The client side tests are 0% flaky. The verification tests are usually less flaky than the end-to-end tests, and never more.</li></ul>Additionally, the new tests are unit tests, so you can run them in your IDE and step through them to debug. These results allowed us to run the end-to-end tests very rarely, only to detect misconfigurations of the interacting services, but not as functional tests. <br /><br />Building and improving test infrastructure to help engineers be more productive is one of the many things test engineers do at Google. Running this project from requirements gathering all the way to a finished product gave me the opportunity to design and implement several prototypes, drive the full implementation of one solution, lead engineering teams to adoption of the new framework, and integrate feedback from engineers and actual measurements into the continuous refinement of the tool. ]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/what-test-engineers-do-at-google-building-test-infrastructure/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Hackable Projects &#8211; Pillar 3: Infrastructure</title>
		<link>https://googledata.org/google-testing/hackable-projects-pillar-3-infrastructure/</link>
		<comments>https://googledata.org/google-testing/hackable-projects-pillar-3-infrastructure/#comments</comments>
		<pubDate>Thu, 10 Nov 2016 19:07:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=637ca2c4bc9e1e152bd61ee6ceac85ed</guid>
		<description><![CDATA[<i>By: Patrik H&#246;glund</i><br /><i><br /></i><i>This is the third article in our series on Hackability; also see <a href="https://testing.googleblog.com/2016/08/hackable-projects.html">the first</a> and <a href="https://testing.googleblog.com/2016/10/hackable-projects-pillar-2-debuggability.html">second article</a>.</i><br /><br /><br />We have seen in our previous articles how <i>Code Health</i> and <i>Debuggability</i> can make a project much easier to work on. The third pillar is a solid infrastructure that gets accurate feedback to your developers as fast as possible. Speed is going to be major theme in this article, and we&#8217;ll look at a number of things you can do to make your project easier to hack on.<br /><br /><h2>Build Systems Speed</h2><div><br /></div><div>Question: What&#8217;s a change you&#8217;d really like to see in our development tools?<br /><br />&#8220;I feel like this question gets asked almost every time, and I always give the same answer: <br />&#160;I would like them to be faster.&#8221; <br />&#160; &#160; &#160; &#160; -- <a href="http://research.google.com/pubs/author37504.html">Ian Lance Taylor</a></div><br /><br />Replace make with <a href="https://ninja-build.org/">ninja</a>. Use the <a href="https://en.wikipedia.org/wiki/Gold_(linker)">gold</a> linker instead of ld. Detect and delete dead code in your project (perhaps using coverage tools). Reduce the number of dependencies, and enforce dependency rules so new ones are not added lightly. Give the developers faster machines. Use distributed build, which is available with many open-source continuous integration systems (or use Google&#8217;s system, <a href="http://www.bazel.io/">Bazel</a>!). You should do everything you can to make the build faster.<br /><br /><div><a href="https://2.bp.blogspot.com/-olHylBpyDck/WCTBuNiPfQI/AAAAAAAAAPM/vqGFMN1aMkUe7ZyYLO4dH0JGjerFPOtvQCLcB/s1600/image04.jpg"><img border="0" height="226" src="https://2.bp.blogspot.com/-olHylBpyDck/WCTBuNiPfQI/AAAAAAAAAPM/vqGFMN1aMkUe7ZyYLO4dH0JGjerFPOtvQCLcB/s400/image04.jpg" width="400"></a></div><div><i>Figure 1: &#8220;Cheetah chasing its prey&#8221; by Marlene Thyssen.</i></div><br /><br />Why is that? There&#8217;s a tremendous difference in hackability if it takes 5 seconds to build and test versus one minute, or even 20 minutes, to build and test. Slow feedback cycles kill hackability, for many reasons:<br /><ul><li>Build and test times longer than a handful of seconds cause many developers&#8217; minds to wander, taking them out of the zone.</li><li>Excessive build or release times* makes tinkering and refactoring much harder. All developers have a threshold when they start hedging (e.g. &#8220;I&#8217;d like to remove this branch, but I don&#8217;t know if I&#8217;ll break the iOS build&#8221;) which causes refactoring to not happen.</li></ul><br /><div><div>* The worst I ever heard of was an OS that took 24 hours to build!</div><div><br /><br /></div><div>How do you actually make fast build systems? There are some suggestions in the first paragraph above, but the best general suggestion I can make is to have a few engineers on the project who deeply understand the build systems and have the time to continuously improve them. The main axes of improvement are:</div><div><ol><li>Reduce the amount of code being compiled.</li><li>Replace tools with faster counterparts.</li><li>Increase processing power, maybe through parallelization or distributed systems.</li></ol></div><div>Note that there is a big difference between <i>full builds</i> and <i>incremental builds</i>. Both should be as fast as possible, but incremental builds are by far the most important to optimize. The way you tackle the two is different. For instance, reducing the total number of source files will make a full build faster, but it may not make an incremental build faster.&#160;</div><div><br /></div><div>To get faster incremental builds, in general, you need to make each source file as decoupled as possible from the rest of the code base. The less a change ripples through the codebase, the less work to do, right? See <a href="https://testing.googleblog.com/2016/08/hackable-projects.html">&#8220;Loose Coupling and Testability&#8221; in Pillar 1</a> for more on this subject. The exact mechanics of dependencies and interfaces depends on programming language - one of the hardest to get right is unsurprisingly C++, where you need to be <a href="https://google.github.io/styleguide/cppguide.html#Forward_Declarations">disciplined with includes and forward declarations</a> to get any kind of incremental build performance.&#160;</div><div><br /></div><div>Build scripts and makefiles should be held to standards as high as the code itself. Technical debt and unnecessary dependencies have a tendency to accumulate in build scripts, because no one has the time to understand and fix them. Avoid this by addressing the technical debt as you go.<br /><br /></div><div><h2>Continuous Integration and Presubmit Queues</h2><div><br /></div>You should build and run tests on all platforms you release on. For instance, if you release on all the major desktop platforms, but all your developers are on Linux, this becomes extra important. It&#8217;s bad for hackability to update the repo, build on Windows, and find that lots of stuff is broken. It&#8217;s even worse if broken changes start to stack on top of each other. I think we all know that terrible feeling: when you&#8217;re not sure your change is the one that broke things.</div><div><br /></div><div>At a minimum, you should build and test on all platforms, but it&#8217;s even better if you do it in presubmit. The <a href="https://dev.chromium.org/developers/testing/commit-queue">Chromium submit queue</a> does this. It has developed over the years so that a normal patch builds and tests on about 30 different build configurations before commit. This is necessary for the 400-patches-per-day velocity of the Chrome project. Most projects obviously don&#8217;t have to go that far. Chromium&#8217;s infrastructure is based off <a href="http://buildbot.net/">BuildBot</a>, but there are many other job scheduling systems depending on your needs.</div></div><div><br /></div><div><div><a href="https://3.bp.blogspot.com/-24eTelErgpc/WCTCuC0wDsI/AAAAAAAAAPU/it0o56UJybMZaZPBOz-MDLhbe-ljyqAtwCLcB/s1600/image02.png"><img border="0" src="https://3.bp.blogspot.com/-24eTelErgpc/WCTCuC0wDsI/AAAAAAAAAPU/it0o56UJybMZaZPBOz-MDLhbe-ljyqAtwCLcB/s1600/image02.png"></a></div><div><i>Figure 2: How a Chromium patch is tested.</i></div></div><div><div><br /></div><div>As we discussed in Build Systems, speed and correctness are critical here. It takes a lot of ongoing work to keep build, tests, and presubmits fast and free of flakes. You should never accept flakes, since developers very quickly lose trust in flaky tests and systems. Tooling can help a bit with this; for instance, see the <a href="http://chromium-try-flakes.appspot.com/">Chromium flakiness dashboard</a>.<br /><br /></div><div><h2>Test Speed</h2></div><div><br /></div><div>Speed is a feature, and this is particularly true for developer infrastructure. In general, the longer a test takes to execute, the less valuable it is. My rule of thumb is: if it takes more than a minute to execute, its value is greatly diminished. There are of course some exceptions, such as soak tests or certain performance tests.&#160;</div></div><div><br /></div><div><div><a href="https://4.bp.blogspot.com/-TnsfrijE-HQ/WCTDKNXmWeI/AAAAAAAAAPc/3J0OEpWIMegHrhD4XCMnwaRoUd6qUILQwCLcB/s1600/image07.png"><img border="0" src="https://4.bp.blogspot.com/-TnsfrijE-HQ/WCTDKNXmWeI/AAAAAAAAAPc/3J0OEpWIMegHrhD4XCMnwaRoUd6qUILQwCLcB/s1600/image07.png"></a></div><div><i>Figure 3. Test value.</i></div></div><div><div><br /></div><div>If you have tests that are slower than 60 seconds, they better be incredibly reliable and easily debuggable. A flaky test that takes several minutes to execute often has negative value because it slows down all work in the code it covers. You probably want to build better integration tests on lower levels instead, so you can make them faster and more reliable.</div><div><br /></div><div>If you have many engineers on a project, reducing the time to run the tests can have a big impact. This is one reason why it&#8217;s great to have <a href="https://testing.googleblog.com/2016/03/from-qa-to-engineering-productivity.html">SETIs</a> or the equivalent. There are many things you can do to improve test speed:</div><div><ul><li><a href="https://github.com/google/gtest-parallel">Sharding and parallelization</a>. Add more machines to your continuous build as your test set or number of developers grows.</li><li>Continuously measure how long it takes to run one build+test cycle in your continuous build, and have someone take action when it gets slower.</li><li>Remove tests that don&#8217;t pull their weight. If a test is really slow, it&#8217;s often because of <a href="http://googletesting.blogspot.se/2008/10/gui-testing-dont-sleep-without.html">poorly written wait conditions</a> or because the test bites off more than it can chew (maybe that unit test doesn&#8217;t have to process 15000 audio frames, maybe 50 is enough).</li><li>If you have tests that bring up a local server stack, for instance inter-server integration tests, making your servers boot faster is going to make the tests faster as well. Faster production code is faster to test! See Running on Localhost, in <a href="https://testing.googleblog.com/2016/10/hackable-projects-pillar-2-debuggability.html">Pillar 2</a> for more on local server stacks.</li></ul></div><div><br /><h2>Workflow Speed</h2></div><div><br />We&#8217;ve talked about fast builds and tests, but the core developer workflows are also important, of course. Chromium undertook multi-year project to switch from Subversion to Git, partly because Subversion was becoming too slow. You need to keep track of your core workflows as your project grows. Your version control system may work fine for years, but become too slow once the project becomes big enough. Bug search and management must also be robust and fast, since this is generally systems developers touch every day.<br /><br /></div><div><h2>Release Often</h2></div><div><br />It aids hackability to <a href="https://en.wikipedia.org/wiki/Release_early,_release_often">deploy to real users as fast as possible</a>. No matter how good your product's tests are, there's always a risk that there's something you haven't thought of. If you&#8217;re building a service or web site, you should aim to deploy multiple times per week. For client projects, <a href="https://blog.chromium.org/2010/07/release-early-release-often.html">Chrome&#8217;s six-weeks cycle</a> is a good goal to aim for.</div><div><br /></div><div>You should invest in infrastructure and tests that give you the confidence to do this - you don&#8217;t want to push something that&#8217;s broken. Your developers will thank you for it, since it makes their jobs so much easier. By releasing often, you mitigate risk, and developers will rush less to hack late changes in the release (since they know the next release isn&#8217;t far off).<br /><br /></div><div><h2>Easy Reverts</h2></div><div><br />If you look in the commit log for the Chromium project, you will see that a significant percentage of the commits are reverts of a previous commits. In Chromium, bad commits quickly become costly because they impede other engineers, and the high velocity can cause good changes to stack onto bad changes.&#160;</div></div><div><br /></div><div><div><a href="https://4.bp.blogspot.com/-AV5gYtJ0eXY/WCTD6w-yzjI/AAAAAAAAAPg/XrnpxKHkF88qkzjLV28E1KmoKz4tvvfUwCLcB/s1600/image08.png"><img border="0" src="https://4.bp.blogspot.com/-AV5gYtJ0eXY/WCTD6w-yzjI/AAAAAAAAAPg/XrnpxKHkF88qkzjLV28E1KmoKz4tvvfUwCLcB/s1600/image08.png"></a></div></div><div><div><div><i>Figure 4: Chromium&#8217;s revert button.</i></div></div><div><div><br /></div></div><div><br />This is why the policy is &#8220;revert first, ask questions later&#8221;. I believe a revert-first policy is good for small projects as well, since it creates a clear expectation that the product/tools/dev environment should be <i>working</i> at all times (and if it doesn&#8217;t, a recent change should probably be reverted).</div><div><br /></div><div>It has a wonderful effect when a revert is simple to make. You can suddenly make <i>speculative reverts</i> if a test went flaky or a performance test regressed. It follows that if a patch is easy to revert, so is the inverse (i.e. reverting the revert or relanding the patch). So if you were wrong and that patch wasn&#8217;t guilty after all, it&#8217;s simple to re-land it again and try reverting another patch. Developers might initially balk at this (because it can&#8217;t possibly be their patch, right?), but they usually come around when they realize the benefits.</div><div><br /></div><div>For many projects, a revert can simply be</div><div><span>git revert 9fbadbeef</span></div><div><span>git push origin master</span></div><div><br /></div><div><br />If your project (wisely) involves code review, it will behoove you to add something like Chromium&#8217;s revert button that I mentioned above. The revert button will create a special patch that bypasses review and tests (since we can assume a clean revert takes us back to a more stable state rather than the opposite). See <a href="https://testing.googleblog.com/2016/08/hackable-projects.html">Pillar 1</a> for more on code review and its benefits.</div><div><br /></div><div>For some projects, reverts are going to be harder, especially if you have a slow or laborious release process. Even if you release often, you could still have problems if a revert involves state migrations in your live services (for instance when rolling back a database schema change). You need to have a strategy to deal with such state changes.&#160;</div><div><br /></div><div><br /></div><div>Reverts must always put you back to safer ground, and everyone must be confident they can safely revert. If not, you run the risk of massive fire drills and lost user trust if a bad patch makes it through the tests and you can&#8217;t revert it.<br /><br /></div><div><h2>Performance Tests: Measure Everything</h2></div><div><br />Is it critical that your app starts up within a second? Should your app always render at 60 fps when it&#8217;s scrolled up or down? Should your web server always serve a response within 100 ms? Should your mobile app be smaller than 8 MB? If so, you should make a performance test for that. Performance tests aid hackability since developers can quickly see how their change affects performance and thus prevent performance regressions from making it into the wild.</div><div><br /></div><div>You should run your automated performance tests on the same device; all devices are different and this will reflect in the numbers. This is fairly straightforward if you have a decent continuous integration system that runs tests sequentially on a known set of worker machines. It&#8217;s harder if you need to run on physical phones or tablets, but it can be done.&#160;</div><div><br /></div><div>A test can be as simple as invoking a particular algorithm and measuring the time it takes to execute it (median and 90th percentile, say, over N runs).</div></div><div><br /></div><div><div><a href="https://1.bp.blogspot.com/-wOxZrXJCrOw/WCTEakhXI4I/AAAAAAAAAPk/EfuFAdV-3YkW-IOLO3Lgv2zursRFmP00wCLcB/s1600/image03.png"><img border="0" height="172" src="https://1.bp.blogspot.com/-wOxZrXJCrOw/WCTEakhXI4I/AAAAAAAAAPk/EfuFAdV-3YkW-IOLO3Lgv2zursRFmP00wCLcB/s400/image03.png" width="400"></a></div><div><i>Figure 5: A VP8-in-WebRTC regression (<a href="https://bugs.chromium.org/p/chromium/issues/detail?id=597705">bug</a>) and its fix displayed in a Catapult dashboard.</i></div></div><div><div><div><br /></div></div><div><br />Write your test so it outputs performance numbers you care about. But what to do with those numbers? Fortunately, Chrome&#8217;s performance test framework <a href="https://github.com/catapult-project/catapult">has been open-sourced</a>, which means you can set up a dashboard, with automatic regression monitoring, with minimal effort. The test framework also includes the powerful <a href="https://github.com/catapult-project/catapult/blob/master/telemetry/README.md">Telemetry</a> framework which can run actions on web pages and Android apps and report performance results. Telemetry and Catapult are battle-tested by use in the Chromium project and are capable of running on a wide set of devices, while getting the maximum of usable performance data out of the devices.<br /><br /></div><div><h2>Sources</h2></div><div><br />Figure 1: By Malene Thyssen (Own work) [CC BY-SA 3.0 (<a href="http://creativecommons.org/licenses/by-sa/3.0">http://creativecommons.org/licenses/by-sa/3.0</a>)], via Wikimedia Commons</div></div><div><br /></div><div><br /></div>]]></description>
				<content:encoded><![CDATA[<i>By: Patrik Höglund</i><br /><i><br /></i><i>This is the third article in our series on Hackability; also see <a href="https://testing.googleblog.com/2016/08/hackable-projects.html">the first</a> and <a href="https://testing.googleblog.com/2016/10/hackable-projects-pillar-2-debuggability.html">second article</a>.</i><br /><br /><br />We have seen in our previous articles how <i>Code Health</i> and <i>Debuggability</i> can make a project much easier to work on. The third pillar is a solid infrastructure that gets accurate feedback to your developers as fast as possible. Speed is going to be major theme in this article, and we’ll look at a number of things you can do to make your project easier to hack on.<br /><br /><h2>Build Systems Speed</h2><div><br /></div><div style="border: 1px solid black; padding: 10px;">Question: What’s a change you’d really like to see in our development tools?<br /><br />“I feel like this question gets asked almost every time, and I always give the same answer: <br />&nbsp;I would like them to be faster.” <br />&nbsp; &nbsp; &nbsp; &nbsp; -- <a href="http://research.google.com/pubs/author37504.html">Ian Lance Taylor</a></div><br /><br />Replace make with <a href="https://ninja-build.org/">ninja</a>. Use the <a href="https://en.wikipedia.org/wiki/Gold_(linker)">gold</a> linker instead of ld. Detect and delete dead code in your project (perhaps using coverage tools). Reduce the number of dependencies, and enforce dependency rules so new ones are not added lightly. Give the developers faster machines. Use distributed build, which is available with many open-source continuous integration systems (or use Google’s system, <a href="http://www.bazel.io/">Bazel</a>!). You should do everything you can to make the build faster.<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://2.bp.blogspot.com/-olHylBpyDck/WCTBuNiPfQI/AAAAAAAAAPM/vqGFMN1aMkUe7ZyYLO4dH0JGjerFPOtvQCLcB/s1600/image04.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="226" src="https://2.bp.blogspot.com/-olHylBpyDck/WCTBuNiPfQI/AAAAAAAAAPM/vqGFMN1aMkUe7ZyYLO4dH0JGjerFPOtvQCLcB/s400/image04.jpg" width="400" /></a></div><div style="text-align: center;"><i>Figure 1: “Cheetah chasing its prey” by Marlene Thyssen.</i></div><br /><br />Why is that? There’s a tremendous difference in hackability if it takes 5 seconds to build and test versus one minute, or even 20 minutes, to build and test. Slow feedback cycles kill hackability, for many reasons:<br /><ul><li>Build and test times longer than a handful of seconds cause many developers’ minds to wander, taking them out of the zone.</li><li>Excessive build or release times* makes tinkering and refactoring much harder. All developers have a threshold when they start hedging (e.g. “I’d like to remove this branch, but I don’t know if I’ll break the iOS build”) which causes refactoring to not happen.</li></ul><br /><div><div>* The worst I ever heard of was an OS that took 24 hours to build!</div><div><br /><br /></div><div>How do you actually make fast build systems? There are some suggestions in the first paragraph above, but the best general suggestion I can make is to have a few engineers on the project who deeply understand the build systems and have the time to continuously improve them. The main axes of improvement are:</div><div><ol><li>Reduce the amount of code being compiled.</li><li>Replace tools with faster counterparts.</li><li>Increase processing power, maybe through parallelization or distributed systems.</li></ol></div><div>Note that there is a big difference between <i>full builds</i> and <i>incremental builds</i>. Both should be as fast as possible, but incremental builds are by far the most important to optimize. The way you tackle the two is different. For instance, reducing the total number of source files will make a full build faster, but it may not make an incremental build faster.&nbsp;</div><div><br /></div><div>To get faster incremental builds, in general, you need to make each source file as decoupled as possible from the rest of the code base. The less a change ripples through the codebase, the less work to do, right? See <a href="https://testing.googleblog.com/2016/08/hackable-projects.html">“Loose Coupling and Testability” in Pillar 1</a> for more on this subject. The exact mechanics of dependencies and interfaces depends on programming language - one of the hardest to get right is unsurprisingly C++, where you need to be <a href="https://google.github.io/styleguide/cppguide.html#Forward_Declarations">disciplined with includes and forward declarations</a> to get any kind of incremental build performance.&nbsp;</div><div><br /></div><div>Build scripts and makefiles should be held to standards as high as the code itself. Technical debt and unnecessary dependencies have a tendency to accumulate in build scripts, because no one has the time to understand and fix them. Avoid this by addressing the technical debt as you go.<br /><br /></div><div><h2>Continuous Integration and Presubmit Queues</h2><div><br /></div>You should build and run tests on all platforms you release on. For instance, if you release on all the major desktop platforms, but all your developers are on Linux, this becomes extra important. It’s bad for hackability to update the repo, build on Windows, and find that lots of stuff is broken. It’s even worse if broken changes start to stack on top of each other. I think we all know that terrible feeling: when you’re not sure your change is the one that broke things.</div><div><br /></div><div>At a minimum, you should build and test on all platforms, but it’s even better if you do it in presubmit. The <a href="https://dev.chromium.org/developers/testing/commit-queue">Chromium submit queue</a> does this. It has developed over the years so that a normal patch builds and tests on about 30 different build configurations before commit. This is necessary for the 400-patches-per-day velocity of the Chrome project. Most projects obviously don’t have to go that far. Chromium’s infrastructure is based off <a href="http://buildbot.net/">BuildBot</a>, but there are many other job scheduling systems depending on your needs.</div></div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://3.bp.blogspot.com/-24eTelErgpc/WCTCuC0wDsI/AAAAAAAAAPU/it0o56UJybMZaZPBOz-MDLhbe-ljyqAtwCLcB/s1600/image02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://3.bp.blogspot.com/-24eTelErgpc/WCTCuC0wDsI/AAAAAAAAAPU/it0o56UJybMZaZPBOz-MDLhbe-ljyqAtwCLcB/s1600/image02.png" /></a></div><div style="text-align: center;"><i>Figure 2: How a Chromium patch is tested.</i></div></div><div><div><br /></div><div>As we discussed in Build Systems, speed and correctness are critical here. It takes a lot of ongoing work to keep build, tests, and presubmits fast and free of flakes. You should never accept flakes, since developers very quickly lose trust in flaky tests and systems. Tooling can help a bit with this; for instance, see the <a href="http://chromium-try-flakes.appspot.com/">Chromium flakiness dashboard</a>.<br /><br /></div><div><h2>Test Speed</h2></div><div><br /></div><div>Speed is a feature, and this is particularly true for developer infrastructure. In general, the longer a test takes to execute, the less valuable it is. My rule of thumb is: if it takes more than a minute to execute, its value is greatly diminished. There are of course some exceptions, such as soak tests or certain performance tests.&nbsp;</div></div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://4.bp.blogspot.com/-TnsfrijE-HQ/WCTDKNXmWeI/AAAAAAAAAPc/3J0OEpWIMegHrhD4XCMnwaRoUd6qUILQwCLcB/s1600/image07.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://4.bp.blogspot.com/-TnsfrijE-HQ/WCTDKNXmWeI/AAAAAAAAAPc/3J0OEpWIMegHrhD4XCMnwaRoUd6qUILQwCLcB/s1600/image07.png" /></a></div><div style="text-align: center;"><i>Figure 3. Test value.</i></div></div><div><div><br /></div><div>If you have tests that are slower than 60 seconds, they better be incredibly reliable and easily debuggable. A flaky test that takes several minutes to execute often has negative value because it slows down all work in the code it covers. You probably want to build better integration tests on lower levels instead, so you can make them faster and more reliable.</div><div><br /></div><div>If you have many engineers on a project, reducing the time to run the tests can have a big impact. This is one reason why it’s great to have <a href="https://testing.googleblog.com/2016/03/from-qa-to-engineering-productivity.html">SETIs</a> or the equivalent. There are many things you can do to improve test speed:</div><div><ul><li><a href="https://github.com/google/gtest-parallel">Sharding and parallelization</a>. Add more machines to your continuous build as your test set or number of developers grows.</li><li>Continuously measure how long it takes to run one build+test cycle in your continuous build, and have someone take action when it gets slower.</li><li>Remove tests that don’t pull their weight. If a test is really slow, it’s often because of <a href="http://googletesting.blogspot.se/2008/10/gui-testing-dont-sleep-without.html">poorly written wait conditions</a> or because the test bites off more than it can chew (maybe that unit test doesn’t have to process 15000 audio frames, maybe 50 is enough).</li><li>If you have tests that bring up a local server stack, for instance inter-server integration tests, making your servers boot faster is going to make the tests faster as well. Faster production code is faster to test! See Running on Localhost, in <a href="https://testing.googleblog.com/2016/10/hackable-projects-pillar-2-debuggability.html">Pillar 2</a> for more on local server stacks.</li></ul></div><div><br /><h2>Workflow Speed</h2></div><div><br />We’ve talked about fast builds and tests, but the core developer workflows are also important, of course. Chromium undertook multi-year project to switch from Subversion to Git, partly because Subversion was becoming too slow. You need to keep track of your core workflows as your project grows. Your version control system may work fine for years, but become too slow once the project becomes big enough. Bug search and management must also be robust and fast, since this is generally systems developers touch every day.<br /><br /></div><div><h2>Release Often</h2></div><div><br />It aids hackability to <a href="https://en.wikipedia.org/wiki/Release_early,_release_often">deploy to real users as fast as possible</a>. No matter how good your product's tests are, there's always a risk that there's something you haven't thought of. If you’re building a service or web site, you should aim to deploy multiple times per week. For client projects, <a href="https://blog.chromium.org/2010/07/release-early-release-often.html">Chrome’s six-weeks cycle</a> is a good goal to aim for.</div><div><br /></div><div>You should invest in infrastructure and tests that give you the confidence to do this - you don’t want to push something that’s broken. Your developers will thank you for it, since it makes their jobs so much easier. By releasing often, you mitigate risk, and developers will rush less to hack late changes in the release (since they know the next release isn’t far off).<br /><br /></div><div><h2>Easy Reverts</h2></div><div><br />If you look in the commit log for the Chromium project, you will see that a significant percentage of the commits are reverts of a previous commits. In Chromium, bad commits quickly become costly because they impede other engineers, and the high velocity can cause good changes to stack onto bad changes.&nbsp;</div></div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://4.bp.blogspot.com/-AV5gYtJ0eXY/WCTD6w-yzjI/AAAAAAAAAPg/XrnpxKHkF88qkzjLV28E1KmoKz4tvvfUwCLcB/s1600/image08.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://4.bp.blogspot.com/-AV5gYtJ0eXY/WCTD6w-yzjI/AAAAAAAAAPg/XrnpxKHkF88qkzjLV28E1KmoKz4tvvfUwCLcB/s1600/image08.png" /></a></div></div><div><div><div style="text-align: center;"><i>Figure 4: Chromium’s revert button.</i></div></div><div><div style="text-align: center;"><br /></div></div><div><br />This is why the policy is “revert first, ask questions later”. I believe a revert-first policy is good for small projects as well, since it creates a clear expectation that the product/tools/dev environment should be <i>working</i> at all times (and if it doesn’t, a recent change should probably be reverted).</div><div><br /></div><div>It has a wonderful effect when a revert is simple to make. You can suddenly make <i>speculative reverts</i> if a test went flaky or a performance test regressed. It follows that if a patch is easy to revert, so is the inverse (i.e. reverting the revert or relanding the patch). So if you were wrong and that patch wasn’t guilty after all, it’s simple to re-land it again and try reverting another patch. Developers might initially balk at this (because it can’t possibly be their patch, right?), but they usually come around when they realize the benefits.</div><div><br /></div><div>For many projects, a revert can simply be</div><div><span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">git revert 9fbadbeef</span></div><div><span style="font-family: &quot;courier new&quot; , &quot;courier&quot; , monospace;">git push origin master</span></div><div><br /></div><div><br />If your project (wisely) involves code review, it will behoove you to add something like Chromium’s revert button that I mentioned above. The revert button will create a special patch that bypasses review and tests (since we can assume a clean revert takes us back to a more stable state rather than the opposite). See <a href="https://testing.googleblog.com/2016/08/hackable-projects.html">Pillar 1</a> for more on code review and its benefits.</div><div><br /></div><div>For some projects, reverts are going to be harder, especially if you have a slow or laborious release process. Even if you release often, you could still have problems if a revert involves state migrations in your live services (for instance when rolling back a database schema change). You need to have a strategy to deal with such state changes.&nbsp;</div><div><br /></div><div><br /></div><div>Reverts must always put you back to safer ground, and everyone must be confident they can safely revert. If not, you run the risk of massive fire drills and lost user trust if a bad patch makes it through the tests and you can’t revert it.<br /><br /></div><div><h2>Performance Tests: Measure Everything</h2></div><div><br />Is it critical that your app starts up within a second? Should your app always render at 60 fps when it’s scrolled up or down? Should your web server always serve a response within 100 ms? Should your mobile app be smaller than 8 MB? If so, you should make a performance test for that. Performance tests aid hackability since developers can quickly see how their change affects performance and thus prevent performance regressions from making it into the wild.</div><div><br /></div><div>You should run your automated performance tests on the same device; all devices are different and this will reflect in the numbers. This is fairly straightforward if you have a decent continuous integration system that runs tests sequentially on a known set of worker machines. It’s harder if you need to run on physical phones or tablets, but it can be done.&nbsp;</div><div><br /></div><div>A test can be as simple as invoking a particular algorithm and measuring the time it takes to execute it (median and 90th percentile, say, over N runs).</div></div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-wOxZrXJCrOw/WCTEakhXI4I/AAAAAAAAAPk/EfuFAdV-3YkW-IOLO3Lgv2zursRFmP00wCLcB/s1600/image03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="172" src="https://1.bp.blogspot.com/-wOxZrXJCrOw/WCTEakhXI4I/AAAAAAAAAPk/EfuFAdV-3YkW-IOLO3Lgv2zursRFmP00wCLcB/s400/image03.png" width="400" /></a></div><div style="text-align: center;"><i>Figure 5: A VP8-in-WebRTC regression (<a href="https://bugs.chromium.org/p/chromium/issues/detail?id=597705">bug</a>) and its fix displayed in a Catapult dashboard.</i></div></div><div><div><div style="text-align: center;"><br /></div></div><div><br />Write your test so it outputs performance numbers you care about. But what to do with those numbers? Fortunately, Chrome’s performance test framework <a href="https://github.com/catapult-project/catapult">has been open-sourced</a>, which means you can set up a dashboard, with automatic regression monitoring, with minimal effort. The test framework also includes the powerful <a href="https://github.com/catapult-project/catapult/blob/master/telemetry/README.md">Telemetry</a> framework which can run actions on web pages and Android apps and report performance results. Telemetry and Catapult are battle-tested by use in the Chromium project and are capable of running on a wide set of devices, while getting the maximum of usable performance data out of the devices.<br /><br /></div><div><h2>Sources</h2></div><div><br />Figure 1: By Malene Thyssen (Own work) [CC BY-SA 3.0 (<a href="http://creativecommons.org/licenses/by-sa/3.0">http://creativecommons.org/licenses/by-sa/3.0</a>)], via Wikimedia Commons</div></div><div><br /></div><div><br /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/hackable-projects-pillar-3-infrastructure/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Hackable Projects &#8211; Pillar 2: Debuggability</title>
		<link>https://googledata.org/google-testing/hackable-projects-pillar-2-debuggability/</link>
		<comments>https://googledata.org/google-testing/hackable-projects-pillar-2-debuggability/#comments</comments>
		<pubDate>Tue, 11 Oct 2016 16:04:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=cf6f003f947782ff80e988e208b171f9</guid>
		<description><![CDATA[<i>By: Patrik H&#246;glund </i><br /><i><br /></i><em>This is the second article in our series on Hackability; also see <a href="https://testing.googleblog.com/2016/08/hackable-projects.html">the first article</a>.</em><br /><em><br /></em><br /><div>&#8220;Deep into that darkness peering, long I stood there, wondering, fearing, doubting, dreaming dreams no mortal ever dared to dream before.&#8221;   -- Edgar Allan Poe</div><br /><br />Debuggability can mean being able to use a debugger, but here we&#8217;re interested in a broader meaning. Debuggability means being able to easily find what&#8217;s wrong with a piece of software, whether it&#8217;s through logs, statistics or debugger tools. Debuggability doesn&#8217;t happen by accident: you need to design it into your product. The amount of work it takes will vary depending on your product, programming language(s) and development environment. <br /><br />In this article, I am going to walk through a few examples of how we have aided debuggability for our developers. If you do the same analysis and implementation for your project, perhaps you can help your developers illuminate the dark corners of the codebase and learn what truly goes on there.<br /><div><a href="https://1.bp.blogspot.com/-1WOvm87QI-U/V_0IEnBp4pI/AAAAAAAAAOs/mCppX2KO2jUWmKpXgNdJlepqKPBvRy0eQCLcB/s1600/image00.jpg"><img border="0" height="315" src="https://1.bp.blogspot.com/-1WOvm87QI-U/V_0IEnBp4pI/AAAAAAAAAOs/mCppX2KO2jUWmKpXgNdJlepqKPBvRy0eQCLcB/s400/image00.jpg" width="400"></a></div><div><em>Figure 1: computer log entry from the </em>Mark II<em>, with a moth taped to the page.</em></div><br /><h2>Running on Localhost </h2><div>Read more on the Testing Blog: <a href="http://testing.googleblog.com/2012/10/hermetic-servers.html">Hermetic Servers</a> by Chaitali Narla and Diego Salas </div><br /><br />Suppose you&#8217;re developing a service with a mobile app that connects to that service. You&#8217;re working on a new feature in the app that requires changes in the backend. Do you develop in production? That&#8217;s a really bad idea, as you must push unfinished code to production to work on your change. Don&#8217;t do that: it could break your service for your existing users. Instead, you need some kind of script that brings up your <a href="http://testing.googleblog.com/2012/10/hermetic-servers.html">server stack on localhost</a>. <br /><br />You can probably run your servers by hand, but that quickly gets tedious. In Google, we usually use fancy python scripts that invoke the server binaries with flags. Why do we need those flags? Suppose, for instance, that you have a server A that depends on a server B and C. The default behavior when the server boots should be to connect to B and C in production. When booting on localhost, we want to connect to our local B and C though. For instance: <br /><br /><pre>b_serv --port=1234 --db=/tmp/fakedb<br />c_serv --port=1235<br />a_serv --b_spec=localhost:1234 --c_spec=localhost:1235<br /></pre><br />That makes it a whole lot easier to develop and debug your server. Make sure the logs and stdout/stderr end up in some well-defined directory on localhost so you don&#8217;t waste time looking for them. You may want to write a basic debug client that sends HTTP requests or RPCs or whatever your server handles. It&#8217;s painful to have to boot the real app on a mobile phone just to test something. <br /><br />A localhost setup is also a prerequisite for making <em>hermetic tests,</em>where the test invokes the above script to bring up the server stack. The test can then run, say, integration tests among the servers or even client-server integration tests. Such integration tests can catch protocol drift bugs between client and server, while being super stable by not talking to external or shared services. <br /><h2>Debugging Mobile Apps</h2>First, mobile is hard. The tooling is generally less mature than for desktop, although things are steadily improving. Again, unit tests are great for hackability here. It&#8217;s really painful to always load your app on a phone connected to your workstation to see if a change worked. <a href="http://robolectric.org/">Robolectric unit tests</a> and <a href="https://google.github.io/android-testing-support-library/docs/espresso/basics/index.html">Espresso functional tests</a>, for instance, run on your workstation and do not require a real phone. <a href="https://developer.apple.com/reference/xctest">xcTests</a>and <a href="https://github.com/google/EarlGrey">Earl Grey</a> give you the same on iOS. <br /><br />Debuggers ship with Xcode and Android Studio. If your Android app ships JNI code, it&#8217;s a bit trickier, but you can attach GDB to running processes on your phone. It&#8217;s worth spending the time figuring this out early in the project, so you don&#8217;t have to guess what your code is doing. Debugging unit tests is even better and can be done straightforwardly on your workstation. <br /><h2>When Debugging gets Tricky</h2>Some products are harder to debug than others. One example is <a href="https://en.wikipedia.org/wiki/Real-time_computing">hard real-time systems</a>, since their behavior is so dependent on timing (and you better not be hooked up to a real industrial controller or rocket engine when you hit a breakpoint!). One possible solution is to run the software on a fake clock instead of a hardware clock, so the clock stops when the program stops. <br /><br />Another example is multi-process sandboxed programs such as Chromium. Since the browser spawns one renderer process per tab, how do you even attach a debugger to it? The developers have made it quite a lot easier with <a href="https://chromium.googlesource.com/chromium/src/+/master/docs/linux_debugging.md#Multiprocess-Tricks">debugging flags and instructions</a>. For instance, this wraps gdb around each renderer process as it starts up: <br /><br /><pre>chrome --renderer-cmd-prefix='xterm -title renderer -e gdb --args'<br /></pre><br />The point is, you need to build these kinds of things into your product; this greatly aids hackability. <br /><h2>Proper Logging</h2><div>Read more on the Testing Blog: <a href="http://testing.googleblog.com/2013/06/optimal-logging.html">Optimal Logging</a> by Anthony Vallone </div><br /><br />It&#8217;s hackability to get the right logs when you need them. It&#8217;s easy to fix a crash if you get a stack trace from the error location. It&#8217;s far from guaranteed you&#8217;ll get such a stack trace, for instance in C++ programs, but this is something you should not stand for. For instance, Chromium had a problem where renderer process crashes didn&#8217;t print in test logs, because the test was running in a separate process. This was later fixed, and this kind of investment is worthwhile to make. A clean stack trace is worth a lot more than a &#8220;renderer crashed&#8221; message. <br /><br />Logs are also useful for development. It&#8217;s an art to determine how much logging is appropriate for a given piece of code, but it is a good idea to keep the default level of logging conservative and give developers the option to turn on more logging for the parts they&#8217;re working on (example: <a href="https://www.chromium.org/for-testers/enable-logging">Chromium</a>). Too much logging isn&#8217;t hackability. <a href="https://googletesting.blogspot.se/2013/06/optimal-logging.html">This article</a> elaborates further on this topic. <br /><br />Logs should also be properly symbolized for C/C++ projects; a naked list of addresses in a stack trace isn&#8217;t very helpful. This is easy if you build for development (e.g. with -g), but if the crash happens in a release build it&#8217;s a bit trickier. You then need to build the same binary with the same flags and use addr2line / ndk-stack / etc to symbolize the stack trace. It&#8217;s a good idea to build tools and scripts for this so it&#8217;s as easy as possible. <br /><h2>Monitoring and Statistics</h2>It aids hackability if developers can quickly understand what effect their changes have in the real world. For this, monitoring tools such as <a href="https://cloud.google.com/stackdriver/">Stackdriver for Google Cloud</a>are excellent. If you&#8217;re running a service, such tools can help you keep track of request volumes and error rates. This way you can quickly detect that 30% increase in request errors, and roll back that bad code change, before it does too much damage. It also makes it possible to debug your service in production without disrupting it. <br /><h2>System Under Test (SUT) Size</h2>Tests and debugging go hand in hand: it&#8217;s a lot easier to target a piece of code in a test than in the whole application. Small and focused tests aid debuggability, because when a test breaks there isn&#8217;t an enormous SUT to look for errors in. These tests will also be less flaky. <a href="http://googletesting.blogspot.se/2015/04/just-say-no-to-more-end-to-end-tests.html">This article</a> discusses this fact at length. <br /><br /><div></div><div><a href="https://3.bp.blogspot.com/-oBuMTeOYhww/V_0IswR5HKI/AAAAAAAAAO0/8jxV5oWkr-ErKGmavjvlRlkVpcGbhnWTACLcB/s1600/img3.png"><img border="0" src="https://3.bp.blogspot.com/-oBuMTeOYhww/V_0IswR5HKI/AAAAAAAAAO0/8jxV5oWkr-ErKGmavjvlRlkVpcGbhnWTACLcB/s1600/img3.png"></a></div><div><em><br /></em><em>Figure 2. The smaller the SUT, the more valuable the test.</em></div><br />You should try to keep the above in mind, particularly when writing integration tests. If you&#8217;re testing a mobile app with a server, what bugs are you actually trying to catch? If you&#8217;re trying to ensure the app can still talk to the server (i.e. catching protocol drift bugs), you should not involve the UI of the app. That&#8217;s not what you&#8217;re testing here. Instead, break out the signaling part of the app into a library, test that directly against your local server stack, and write separate tests for the UI that only test the UI. <br /><br />Smaller SUTs also greatly aids test speed, since there&#8217;s less to build, less to bring up and less to keep running. In general, strive to keep the SUT as small as possible through whatever means necessary. It will keep the tests smaller, faster and more focused. <br /><h2>Sources</h2>Figure 1: By Courtesy of the Naval Surface Warfare Center, Dahlgren, VA., 1988. - U.S. Naval Historical Center Online Library Photograph NH 96566-KN, Public Domain, https://commons.wikimedia.org/w/index.php?curid=165211  <br /><br /><br /><div>(Continue to <a href="https://testing.googleblog.com/2016/11/hackable-projects-pillar-3.html">Pillar 3: Infrastructure</a>)</div><br />]]></description>
				<content:encoded><![CDATA[<i>By: Patrik Höglund </i><br /><i><br /></i><em>This is the second article in our series on Hackability; also see <a href="https://testing.googleblog.com/2016/08/hackable-projects.html">the first article</a>.</em><br /><em><br /></em><br /><div style="border: 1px solid black; padding: 10px;">“Deep into that darkness peering, long I stood there, wondering, fearing, doubting, dreaming dreams no mortal ever dared to dream before.”   -- Edgar Allan Poe</div><br /><br />Debuggability can mean being able to use a debugger, but here we’re interested in a broader meaning. Debuggability means being able to easily find what’s wrong with a piece of software, whether it’s through logs, statistics or debugger tools. Debuggability doesn’t happen by accident: you need to design it into your product. The amount of work it takes will vary depending on your product, programming language(s) and development environment. <br /><br />In this article, I am going to walk through a few examples of how we have aided debuggability for our developers. If you do the same analysis and implementation for your project, perhaps you can help your developers illuminate the dark corners of the codebase and learn what truly goes on there.<br /><div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-1WOvm87QI-U/V_0IEnBp4pI/AAAAAAAAAOs/mCppX2KO2jUWmKpXgNdJlepqKPBvRy0eQCLcB/s1600/image00.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="315" src="https://1.bp.blogspot.com/-1WOvm87QI-U/V_0IEnBp4pI/AAAAAAAAAOs/mCppX2KO2jUWmKpXgNdJlepqKPBvRy0eQCLcB/s400/image00.jpg" width="400" /></a></div><div style="text-align: center;"><em>Figure 1: computer log entry from the </em>Mark II<em>, with a moth taped to the page.</em></div><br /><h2>Running on Localhost </h2><div style="border: 1px solid black; padding: 10px;">Read more on the Testing Blog: <a href="http://testing.googleblog.com/2012/10/hermetic-servers.html">Hermetic Servers</a> by Chaitali Narla and Diego Salas </div><br /><br />Suppose you’re developing a service with a mobile app that connects to that service. You’re working on a new feature in the app that requires changes in the backend. Do you develop in production? That’s a really bad idea, as you must push unfinished code to production to work on your change. Don’t do that: it could break your service for your existing users. Instead, you need some kind of script that brings up your <a href="http://testing.googleblog.com/2012/10/hermetic-servers.html">server stack on localhost</a>. <br /><br />You can probably run your servers by hand, but that quickly gets tedious. In Google, we usually use fancy python scripts that invoke the server binaries with flags. Why do we need those flags? Suppose, for instance, that you have a server A that depends on a server B and C. The default behavior when the server boots should be to connect to B and C in production. When booting on localhost, we want to connect to our local B and C though. For instance: <br /><br /><pre class="prettyprint">b_serv --port=1234 --db=/tmp/fakedb<br />c_serv --port=1235<br />a_serv --b_spec=localhost:1234 --c_spec=localhost:1235<br /></pre><br />That makes it a whole lot easier to develop and debug your server. Make sure the logs and stdout/stderr end up in some well-defined directory on localhost so you don’t waste time looking for them. You may want to write a basic debug client that sends HTTP requests or RPCs or whatever your server handles. It’s painful to have to boot the real app on a mobile phone just to test something. <br /><br />A localhost setup is also a prerequisite for making <em>hermetic tests,</em>where the test invokes the above script to bring up the server stack. The test can then run, say, integration tests among the servers or even client-server integration tests. Such integration tests can catch protocol drift bugs between client and server, while being super stable by not talking to external or shared services. <br /><h2>Debugging Mobile Apps</h2>First, mobile is hard. The tooling is generally less mature than for desktop, although things are steadily improving. Again, unit tests are great for hackability here. It’s really painful to always load your app on a phone connected to your workstation to see if a change worked. <a href="http://robolectric.org/">Robolectric unit tests</a> and <a href="https://google.github.io/android-testing-support-library/docs/espresso/basics/index.html">Espresso functional tests</a>, for instance, run on your workstation and do not require a real phone. <a href="https://developer.apple.com/reference/xctest">xcTests</a>and <a href="https://github.com/google/EarlGrey">Earl Grey</a> give you the same on iOS. <br /><br />Debuggers ship with Xcode and Android Studio. If your Android app ships JNI code, it’s a bit trickier, but you can attach GDB to running processes on your phone. It’s worth spending the time figuring this out early in the project, so you don’t have to guess what your code is doing. Debugging unit tests is even better and can be done straightforwardly on your workstation. <br /><h2>When Debugging gets Tricky</h2>Some products are harder to debug than others. One example is <a href="https://en.wikipedia.org/wiki/Real-time_computing">hard real-time systems</a>, since their behavior is so dependent on timing (and you better not be hooked up to a real industrial controller or rocket engine when you hit a breakpoint!). One possible solution is to run the software on a fake clock instead of a hardware clock, so the clock stops when the program stops. <br /><br />Another example is multi-process sandboxed programs such as Chromium. Since the browser spawns one renderer process per tab, how do you even attach a debugger to it? The developers have made it quite a lot easier with <a href="https://chromium.googlesource.com/chromium/src/+/master/docs/linux_debugging.md#Multiprocess-Tricks">debugging flags and instructions</a>. For instance, this wraps gdb around each renderer process as it starts up: <br /><br /><pre class="prettyprint">chrome --renderer-cmd-prefix='xterm -title renderer -e gdb --args'<br /></pre><br />The point is, you need to build these kinds of things into your product; this greatly aids hackability. <br /><h2>Proper Logging</h2><div style="border: 1px solid black; padding: 10px;">Read more on the Testing Blog: <a href="http://testing.googleblog.com/2013/06/optimal-logging.html">Optimal Logging</a> by Anthony Vallone </div><br /><br />It’s hackability to get the right logs when you need them. It’s easy to fix a crash if you get a stack trace from the error location. It’s far from guaranteed you’ll get such a stack trace, for instance in C++ programs, but this is something you should not stand for. For instance, Chromium had a problem where renderer process crashes didn’t print in test logs, because the test was running in a separate process. This was later fixed, and this kind of investment is worthwhile to make. A clean stack trace is worth a lot more than a “renderer crashed” message. <br /><br />Logs are also useful for development. It’s an art to determine how much logging is appropriate for a given piece of code, but it is a good idea to keep the default level of logging conservative and give developers the option to turn on more logging for the parts they’re working on (example: <a href="https://www.chromium.org/for-testers/enable-logging">Chromium</a>). Too much logging isn’t hackability. <a href="https://googletesting.blogspot.se/2013/06/optimal-logging.html">This article</a> elaborates further on this topic. <br /><br />Logs should also be properly symbolized for C/C++ projects; a naked list of addresses in a stack trace isn’t very helpful. This is easy if you build for development (e.g. with -g), but if the crash happens in a release build it’s a bit trickier. You then need to build the same binary with the same flags and use addr2line / ndk-stack / etc to symbolize the stack trace. It’s a good idea to build tools and scripts for this so it’s as easy as possible. <br /><h2>Monitoring and Statistics</h2>It aids hackability if developers can quickly understand what effect their changes have in the real world. For this, monitoring tools such as <a href="https://cloud.google.com/stackdriver/">Stackdriver for Google Cloud</a>are excellent. If you’re running a service, such tools can help you keep track of request volumes and error rates. This way you can quickly detect that 30% increase in request errors, and roll back that bad code change, before it does too much damage. It also makes it possible to debug your service in production without disrupting it. <br /><h2>System Under Test (SUT) Size</h2>Tests and debugging go hand in hand: it’s a lot easier to target a piece of code in a test than in the whole application. Small and focused tests aid debuggability, because when a test breaks there isn’t an enormous SUT to look for errors in. These tests will also be less flaky. <a href="http://googletesting.blogspot.se/2015/04/just-say-no-to-more-end-to-end-tests.html">This article</a> discusses this fact at length. <br /><br /><div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"><a href="https://3.bp.blogspot.com/-oBuMTeOYhww/V_0IswR5HKI/AAAAAAAAAO0/8jxV5oWkr-ErKGmavjvlRlkVpcGbhnWTACLcB/s1600/img3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://3.bp.blogspot.com/-oBuMTeOYhww/V_0IswR5HKI/AAAAAAAAAO0/8jxV5oWkr-ErKGmavjvlRlkVpcGbhnWTACLcB/s1600/img3.png" /></a></div><div style="text-align: center;"><em><br /></em><em>Figure 2. The smaller the SUT, the more valuable the test.</em></div><br />You should try to keep the above in mind, particularly when writing integration tests. If you’re testing a mobile app with a server, what bugs are you actually trying to catch? If you’re trying to ensure the app can still talk to the server (i.e. catching protocol drift bugs), you should not involve the UI of the app. That’s not what you’re testing here. Instead, break out the signaling part of the app into a library, test that directly against your local server stack, and write separate tests for the UI that only test the UI. <br /><br />Smaller SUTs also greatly aids test speed, since there’s less to build, less to bring up and less to keep running. In general, strive to keep the SUT as small as possible through whatever means necessary. It will keep the tests smaller, faster and more focused. <br /><h2>Sources</h2>Figure 1: By Courtesy of the Naval Surface Warfare Center, Dahlgren, VA., 1988. - U.S. Naval Historical Center Online Library Photograph NH 96566-KN, Public Domain, https://commons.wikimedia.org/w/index.php?curid=165211  <br /><br /><br /><div style="text-align: center;">(Continue to <a href="https://testing.googleblog.com/2016/11/hackable-projects-pillar-3.html">Pillar 3: Infrastructure</a>)</div><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/hackable-projects-pillar-2-debuggability/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Testing on the Toilet: What Makes a Good End-to-End Test?</title>
		<link>https://googledata.org/google-testing/testing-on-the-toilet-what-makes-a-good-end-toend-test/</link>
		<comments>https://googledata.org/google-testing/testing-on-the-toilet-what-makes-a-good-end-toend-test/#comments</comments>
		<pubDate>Wed, 21 Sep 2016 17:23:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=c640d80757b5b95554d3f7ff8d72b120</guid>
		<description><![CDATA[by Adam BenderThis article was adapted from a Google Testing on the Toilet (TotT) episode. You can download a printer-friendly version of this TotT episode and post it in your office.An end-to-end test tests your entire system from one end to the other...]]></description>
				<content:encoded><![CDATA[<em>by Adam Bender</em><br /><em><br /></em><em>This article was adapted from a <a href="http://googletesting.blogspot.com/2007/01/introducing-testing-on-toilet.html">Google Testing on the Toilet</a> (TotT) episode. You can download a <a href="https://docs.google.com/document/d/19aUiPozqFYJ7EqTrzP69ityJ_X1ZCYMmf6Z8nBfuDQo/edit?usp=sharing">printer-friendly version</a> of this TotT episode and post it in your office.</em><br /><br />An end-to-end test tests your entire system from one end to the other, treating everything in between as a black box. <strong><span style="color: #990000;">End-to-end tests can catch bugs that manifest <em>across </em>your entire system</span></strong>. In addition to unit and integration tests, they are a critical part of a balanced testing diet, providing confidence about the health of your system in a near production state. Unfortunately, end-to-end tests are <strong><span style="color: #990000;">slower, more flaky, and more expensive to maintain</span></strong> than unit or integration tests. Consider carefully whether an end-to-end test is warranted, and if so, how best to write one. <br /><br />Let's consider how an end-to-end test might work for the following "login flow":<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-XpDz-avnNhA/V-LBGc9cvtI/AAAAAAAAAOQ/FuzdVujJW8EOTzSUZ0rbUPeg2U2VJh2QgCLcB/s1600/image00.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://1.bp.blogspot.com/-XpDz-avnNhA/V-LBGc9cvtI/AAAAAAAAAOQ/FuzdVujJW8EOTzSUZ0rbUPeg2U2VJh2QgCLcB/s1600/image00.png" /></a></div><br /><br />In order to be cost effective, an end-to-end test should <strong><span style="color: #990000;">focus on aspects of your system that cannot be reliably evaluated with smaller tests</span></strong>, such as resource allocation, concurrency issues and API compatibility. More specifically:<br /><ul><li><strong><span style="color: #990000;">For each important use case, there should be one corresponding end-to-end test</span>.</strong> This should include one test for each important class of error. The goal is the keep your total end-to-end count low. </li><li>Be prepared to <strong><span style="color: #990000;">allocate at least one week a quarter per test to keep your end-to-end tests stable</span> </strong>in the face of issues like slow and flaky dependencies or minor UI changes. </li><li><strong><span style="color: #990000;">Focus your efforts on verifying overall system behavior instead of specific implementation details</span></strong>; for example, when testing login behavior, verify that the process succeeds independent of the exact messages or visual layouts, which may change frequently. </li><li><strong><span style="color: #990000;">Make your end-to-end test easy to debug</span></strong> by providing an overview-level log file, documenting common test failure modes, and preserving all relevant system state information (e.g.: screenshots, database snapshots, etc.).</li></ul>End-to-end tests also come with some important caveats: <br /><ul><li>System components that are owned by other teams may change unexpectedly, and break your tests. This increases overall maintenance cost, but can highlight incompatible changes </li><li><strong><span style="color: #990000;">It may be more difficult to make an end-to-end test fully hermetic</span></strong>; leftover test data may alter future tests and/or production systems. Where possible keep your test data ephemeral. </li><li>An end-to-end test often necessitates multiple test doubles (<a href="https://testing.googleblog.com/2013/07/testing-on-toilet-know-your-test-doubles.html">fakes or stubs</a>) for underlying dependencies; they can, however, have a high maintenance burden as they drift from the real implementations over time.</li></ul>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/testing-on-the-toilet-what-makes-a-good-end-toend-test/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>What Test Engineers do at Google</title>
		<link>https://googledata.org/google-testing/what-test-engineers-do-at-google/</link>
		<comments>https://googledata.org/google-testing/what-test-engineers-do-at-google/#comments</comments>
		<pubDate>Mon, 12 Sep 2016 15:00:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=f1c9595720596f1bcabbcf3204e38f82</guid>
		<description><![CDATA[<i>by Matt Lowrie, Manjusha Parvathaneni, Benjamin Pick,  and Jochen Wuttke </i><br /><br />Test engineers (TEs) at Google are a dedicated group of engineers who use proven testing practices to foster excellence in our products. We orchestrate the rapid testing and releasing of products and features our users rely on. Achieving this velocity requires creative and diverse engineering skills that allow us to advocate for our users. By building testable user journeys into the process, we ensure reliable products. TEs are also the glue that bring together feature stakeholders (product managers, development teams, UX designers, release engineers, beta testers, end users, etc.) to confirm successful product launches. Essentially, every day we ask ourselves, &#8220;How can we make our software development process more efficient to deliver products that make our users happy?&#8221;. <br /><br />The TE role grew out of the desire to make Google&#8217;s early free products, like Search, Gmail and Docs, better than similar paid products on the market at the time. Early on in Google&#8217;s history, a small group of engineers believed that the company&#8217;s &#8220;launch and iterate&#8221; approach to software deployment could be improved with continuous automated testing. They took it upon themselves to promote good testing practices to every team throughout the company, via some programs you may have heard about: <a href="http://googletesting.blogspot.com/2007/01/introducing-testing-on-toilet.html">Testing on the Toilet</a>, the <a href="https://mike-bland.com/2011/10/18/test-certified.html">Test Certified Program</a>, and the <a href="https://developers.google.com/google-test-automation-conference/">Google Test Automation Conference (GTAC)</a>. These efforts resulted in every project taking ownership of all aspects of testing, such as <a href="http://googletesting.blogspot.com/2014/07/measuring-coverage-at-google.html">code coverage</a> and <a href="http://googletesting.blogspot.com/2007/10/performance-testing.html">performance testing</a>. Testing practices quickly became commonplace throughout the company and engineers writing tests for their own code became the standard. Today, TEs carry on this tradition of setting the standard of quality which all products should achieve. <br /><br />Historically, Google has sustained two separate job titles related to product testing and test infrastructure, which has caused confusion. We often get asked what the difference is between the two. The rebranding of the Software engineer, tools and infrastructure (SETI) role, which now concentrates on engineering productivity, has been addressed in a <a href="http://googletesting.blogspot.com/2016/03/from-qa-to-engineering-productivity.html">previous blog post</a>.  What this means for test engineers at Google, is an enhanced responsibility of being the authority on product excellence. We are expected to uphold testing standards company-wide, both programmatically and persuasively. <br /><br />Test engineer is a unique role at Google. As TEs, we define and organize our own engineering projects, bridging gaps between engineering output and end-user satisfaction. To give you an idea of what TEs do, here are some examples of challenges we need to solve on any particular day: <br /><ul><li>Automate a manual verification process for product release candidates so developers have more time to respond to potential release-blocking issues. </li><li>Design and implement an automated way to track and surface Android battery usage to developers, so that they know immediately when a new feature will cause users drained batteries. </li><li>Quantify if a regenerated data set used by a product, which contains a billion entities, is better quality than the data set currently live in production. </li><li>Write an automated test suite that validates if content presented to a user is of an acceptable quality level based on their interests. </li><li>Read an engineering design proposal for a new feature and provide suggestions about how and where to build in testability. </li><li>Investigate correlated stack traces submitted by users through our feedback tracking system, and search the code base to find the correct owner for escalation. </li><li>Collaborate on determining the root cause of a production outage, then pinpoint tests that need to be added to prevent similar outages in the future. </li><li>Organize a task force to advise teams across the company about best practices when testing for accessibility.</li></ul>Over the next few weeks leading up to <a href="https://developers.google.com/google-test-automation-conference/">GTAC</a>, we will also post vignettes of actual TEs working on different projects at Google, to showcase the diversity of the Google Test Engineer role. Stay tuned!]]></description>
				<content:encoded><![CDATA[<i>by Matt Lowrie, Manjusha Parvathaneni, Benjamin Pick,  and Jochen Wuttke </i><br /><br />Test engineers (TEs) at Google are a dedicated group of engineers who use proven testing practices to foster excellence in our products. We orchestrate the rapid testing and releasing of products and features our users rely on. Achieving this velocity requires creative and diverse engineering skills that allow us to advocate for our users. By building testable user journeys into the process, we ensure reliable products. TEs are also the glue that bring together feature stakeholders (product managers, development teams, UX designers, release engineers, beta testers, end users, etc.) to confirm successful product launches. Essentially, every day we ask ourselves, “How can we make our software development process more efficient to deliver products that make our users happy?”. <br /><br />The TE role grew out of the desire to make Google’s early free products, like Search, Gmail and Docs, better than similar paid products on the market at the time. Early on in Google’s history, a small group of engineers believed that the company’s “launch and iterate” approach to software deployment could be improved with continuous automated testing. They took it upon themselves to promote good testing practices to every team throughout the company, via some programs you may have heard about: <a href="http://googletesting.blogspot.com/2007/01/introducing-testing-on-toilet.html">Testing on the Toilet</a>, the <a href="https://mike-bland.com/2011/10/18/test-certified.html">Test Certified Program</a>, and the <a href="https://developers.google.com/google-test-automation-conference/">Google Test Automation Conference (GTAC)</a>. These efforts resulted in every project taking ownership of all aspects of testing, such as <a href="http://googletesting.blogspot.com/2014/07/measuring-coverage-at-google.html">code coverage</a> and <a href="http://googletesting.blogspot.com/2007/10/performance-testing.html">performance testing</a>. Testing practices quickly became commonplace throughout the company and engineers writing tests for their own code became the standard. Today, TEs carry on this tradition of setting the standard of quality which all products should achieve. <br /><br />Historically, Google has sustained two separate job titles related to product testing and test infrastructure, which has caused confusion. We often get asked what the difference is between the two. The rebranding of the Software engineer, tools and infrastructure (SETI) role, which now concentrates on engineering productivity, has been addressed in a <a href="http://googletesting.blogspot.com/2016/03/from-qa-to-engineering-productivity.html">previous blog post</a>.  What this means for test engineers at Google, is an enhanced responsibility of being the authority on product excellence. We are expected to uphold testing standards company-wide, both programmatically and persuasively. <br /><br />Test engineer is a unique role at Google. As TEs, we define and organize our own engineering projects, bridging gaps between engineering output and end-user satisfaction. To give you an idea of what TEs do, here are some examples of challenges we need to solve on any particular day: <br /><ul><li>Automate a manual verification process for product release candidates so developers have more time to respond to potential release-blocking issues. </li><li>Design and implement an automated way to track and surface Android battery usage to developers, so that they know immediately when a new feature will cause users drained batteries. </li><li>Quantify if a regenerated data set used by a product, which contains a billion entities, is better quality than the data set currently live in production. </li><li>Write an automated test suite that validates if content presented to a user is of an acceptable quality level based on their interests. </li><li>Read an engineering design proposal for a new feature and provide suggestions about how and where to build in testability. </li><li>Investigate correlated stack traces submitted by users through our feedback tracking system, and search the code base to find the correct owner for escalation. </li><li>Collaborate on determining the root cause of a production outage, then pinpoint tests that need to be added to prevent similar outages in the future. </li><li>Organize a task force to advise teams across the company about best practices when testing for accessibility.</li></ul>Over the next few weeks leading up to <a href="https://developers.google.com/google-test-automation-conference/">GTAC</a>, we will also post vignettes of actual TEs working on different projects at Google, to showcase the diversity of the Google Test Engineer role. Stay tuned! ]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/what-test-engineers-do-at-google/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Hackable Projects &#8211; Pillar 1: Code Health</title>
		<link>https://googledata.org/google-testing/hackable-projects/</link>
		<comments>https://googledata.org/google-testing/hackable-projects/#comments</comments>
		<pubDate>Thu, 18 Aug 2016 18:14:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=1f7b92bfac3914f912b89814af70d050</guid>
		<description><![CDATA[<em>By: Patrik H&#246;glund </em><br /><h1>Introduction</h1>Software development is difficult. Projects often evolve over several years, under changing requirements and shifting market conditions, impacting developer tools and infrastructure. Technical debt, slow build systems, poor debuggability, and increasing numbers of dependencies can weigh down a project The developers get weary, and cobwebs accumulate in dusty corners of the code base. <br /><br />Fighting these issues can be taxing and feel like a quixotic undertaking, but don&#8217;t worry &#8212; the Google Testing Blog is riding to the rescue! This is the first article of a series on &#8220;hackability&#8221; that identifies some of the issues that hinder software projects and outlines what Google SETIs usually do about them. <br /><br /><a href="https://en.wiktionary.org/wiki/hackable">According to Wiktionary</a>, hackable is defined as: <br /><div><b>Adjective</b><br /><b>hackable</b> &#8206;(comparative <b>more hackable</b>, superlative <b>most hackable</b>) <br /><ol><li>(computing) That can be hacked or broken into; insecure, vulnerable.&#160;</li><li>That lends itself to hacking (technical tinkering and modification); moddable.</li></ol></div><br />Obviously, we&#8217;re not going to talk about making your product more vulnerable (by, say, rolling your own crypto or something equally unwise); instead, we will focus on the second definition, which essentially means &#8220;something that is easy to work on.&#8221; This has become the <a href="http://googletesting.blogspot.com/2016/03/from-qa-to-engineering-productivity.html">mainfocus for SETIs at Google</a> as the role has evolved over the years.<br /><h2>In Practice</h2>In a hackable project, it&#8217;s easy to try things and hard to break things. Hackability means fast feedback cycles that offer useful information to the developer. <br /><br />This is hackability: <br /><ul><li>Developing is easy </li><li>Fast build </li><li>Good, fast tests </li><li>Clean code </li><li>Easy running + debugging </li><li>One-click rollbacks</li></ul>In contrast, what is not hackability? <br /><ul><li>Broken HEAD (tip-of-tree) </li><li>Slow presubmit (i.e. <a href="https://www.chromium.org/developers/how-tos/depottools/presubmit-scripts">checks running before submit</a>) </li><li>Builds take hours </li><li>Incremental build/link &#62; 30s </li><li><a href="http://googletesting.blogspot.com/2016/05/flaky-tests-at-google-and-how-we.html">Flakytests</a></li><li>Can&#8217;t attach debugger </li><li>Logs full of uninteresting information</li></ul><h2>The Three Pillars of Hackability</h2>There are a number of tools and practices that foster hackability. When everything is in place, it feels great to work on the product. Basically no time is spent on figuring out why things are broken, and all time is spent on what matters, which is understanding and working with the code. I believe there are three main pillars that support hackability. If one of them is absent, hackability will suffer. They are: <br /><br /><div><a href="https://3.bp.blogspot.com/-esLisB8th9M/V7XlS7pViVI/AAAAAAAAANs/lSJgkuiOF5w2Eqf1Yt_yaAbHqdwCYlg-gCLcB/s1600/image03.png"><img border="0" height="203" src="https://3.bp.blogspot.com/-esLisB8th9M/V7XlS7pViVI/AAAAAAAAANs/lSJgkuiOF5w2Eqf1Yt_yaAbHqdwCYlg-gCLcB/s320/image03.png" width="320"></a></div><br /><h1>Pillar 1: Code Health</h1><div>&#8220;I found Rome a city of bricks, and left it a city of marble.&#8221;<br />&#160; &#160;-- Augustus</div><br />Keeping the code in good shape is critical for hackability. It&#8217;s a lot harder to tinker and modify something if you don&#8217;t understand what it does (or if it&#8217;s full of hidden traps, for that matter). <br /><h2>Tests</h2>Unit and small integration tests are probably the best things you can do for hackability. They&#8217;re a support you can lean on while making your changes, and they contain lots of good information on what the code does. It isn&#8217;t hackability to boot a slow UI and click buttons on every iteration to verify your change worked - it is hackability to run a sub-second set of unit tests! In contrast, end-to-end (E2E) tests generally help hackability much less (and can <a href="http://googletesting.blogspot.com/2015/04/just-say-no-to-more-end-to-end-tests.html">evenbe a hindrance</a> if they, or the product, are in sufficiently bad shape). <br /><br /><div><a href="https://2.bp.blogspot.com/-H0OCdokbaVw/V7XlkhRcJcI/AAAAAAAAANw/z-v9qXyVig8dspmHHnRu6FQscqSOtvrTgCLcB/s1600/image01.png"><img border="0" height="276" src="https://2.bp.blogspot.com/-H0OCdokbaVw/V7XlkhRcJcI/AAAAAAAAANw/z-v9qXyVig8dspmHHnRu6FQscqSOtvrTgCLcB/s320/image01.png" width="320"></a></div><div><em>Figure 1: the Testing Pyramid.</em></div><br />I&#8217;ve always been interested in how you actually make unit tests happen in a team. It&#8217;s about education. Writing a product such that it has good unit tests is actually a hard problem. It requires knowledge of dependency injection, testing/mocking frameworks, language idioms and refactoring. The difficulty varies by language as well. Writing unit tests in Go or Java is quite easy and natural, whereas in C++ it can be very difficult (and it isn&#8217;t exactly ingrained in C++ culture to write unit tests). <br /><br />It&#8217;s important to educate your developers about unit tests. Sometimes, it is appropriate to lead by example and help review unit tests as well. You can have a large impact on a project by establishing a pattern of unit testing early. If tons of code gets written without unit tests, it will be much harder to add unit tests later. <br /><br />What if you already have tons of poorly tested legacy code? The answer is refactoring and adding tests as you go. It&#8217;s hard work, but each line you add a test for is one more line that is easier to hack on. <br /><h2>Readable Code and Code Review</h2>At Google, &#8220;readability&#8221; is a special committer status that is granted per language (C++, Go, Java and so on). It means that a person not only knows the language and its culture and idioms well, but also can write clean, well tested and well structured code. Readability literally means that you&#8217;re a guardian of Google&#8217;s code base and should push back on hacky and ugly code. The use of a <a href="https://github.com/google/styleguide">style guide</a> enforces consistency, and <a href="https://en.wikipedia.org/wiki/Code_review">code review</a> (where at least one person with readability must approve) ensures the code upholds high quality. Engineers must take care to not depend too much on &#8220;review buddies&#8221; here but really make sure to pull in the person that can give the best feedback. <br /><br />Requiring code reviews naturally results in small changes, as reviewers often get grumpy if you dump huge changelists in their lap (at least if reviewers are somewhat fast to respond, which they should be). This is a good thing, since small changes are less risky and are easy to roll back. Furthermore, code review is good for knowledge sharing. You can also do pair programming if your team prefers that (a pair-programmed change is considered reviewed and can be submitted when both engineers are happy). There are multiple open-source review tools out there, such as <a href="https://www.gerritcodereview.com/">Gerrit</a>. <br /><br />Nice, clean code is great for hackability, since you don&#8217;t need to spend time to unwind that nasty pointer hack in your head before making your changes. How do you make all this happen in practice? Put together workshops on, say, the <a href="https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)">SOLID principles</a>, unit testing, or concurrency to encourage developers to learn. Spread knowledge through code review, pair programming and mentoring (such as with the Readability concept). You can&#8217;t just mandate higher code quality; it takes a lot of work, effort and consistency. <br /><h2>Presubmit Testing and Lint</h2>Consistently formatted source code aids hackability. You can scan code faster if its formatting is consistent. Automated tooling also aids hackability. It really doesn&#8217;t make sense to waste any time on formatting source code by hand. You should be using tools like <a href="https://golang.org/cmd/gofmt/">gofmt</a>, <a href="http://clang.llvm.org/docs/ClangFormat.html">clang-format</a>, etc. If the patch isn&#8217;t formatted properly, you should see something like this (<a href="https://cs.chromium.org/chromium/tools/depot_tools/presubmit_canned_checks.py?q=%22requires+formatting%22&#38;sq=package:chromium&#38;l=1151">example from Chrome</a>): <br /><br /><pre>$ git cl upload<br />Error: the media/audio directory requires formatting. Please run <br />    git cl format media/audio.</pre><br />Source formatting isn&#8217;t the only thing to check. In fact, you should check pretty much anything you have as a rule in your project. Should other modules not depend on the internals of your modules? <a href="https://cs.chromium.org/chromium/src/buildtools/checkdeps/builddeps.py?q=check_deps&#38;sq=package:chromium&#38;dr=C">Enforce it with a check</a>. Are there already inappropriate dependencies in your project? Whitelist the existing ones for now, but at least block new bad dependencies from forming. Should our app work on Android 16 phones and newer? <a href="https://bugs.chromium.org/p/webrtc/issues/detail?id=5063">Add linting</a>, so we don&#8217;t use level 17+ APIs without gating at runtime. Should your project&#8217;s <a href="https://en.wikipedia.org/wiki/VHDL">VHDL</a> code always place-and-route cleanly on a particular brand of <a href="https://en.wikipedia.org/wiki/Field-programmable_gate_array">FPGA</a>? Invoke the layout tool in your presubmit and and stop submit if the layout process fails. <br /><br />Presubmit is the most valuable real estate for aiding hackability. You have limited space in your presubmit, but you can get tremendous value out of it if you put the right things there. You should stop all obvious errors here. <br /><br />It aids hackability to have all this tooling so you don&#8217;t have to waste time going back and breaking things for other developers. Remember you need to maintain the presubmit well; it&#8217;s not hackability to have a slow, overbearing or buggy presubmit. Having a good presubmit can make it tremendously more pleasant to work on a project. We&#8217;re going to talk more in later articles on how to build infrastructure for submit queues and presubmit. <br /><h2>Single Branch And Reducing Risk</h2>Having a single branch for everything, and putting risky new changes behind <a href="https://en.wikipedia.org/wiki/Feature_toggle">feature flags</a>, aids hackability since branches and forks often amass tremendous risk when it&#8217;s time to merge them. Single branches smooth out the risk. Furthermore, running all your tests on many branches is expensive. However, a single branch can have negative effects on hackability if Team A depends on a library from Team B and gets broken by Team B a lot. Having some kind of stabilization on Team B&#8217;s software might be a good idea there. <a href="https://googletesting.blogspot.com/2015/05/multi-repository-development.html">Thisarticle</a> covers such situations, and how to integrate often with your dependencies to reduce the risk that one of them will break you. <br /><h2>Loose Coupling and Testability</h2>Tightly coupled code is terrible for hackability. To take the most ridiculous example I know: I once heard of a computer game where a developer changed a ballistics algorithm and broke the game&#8217;s <em>chat</em>. That&#8217;s hilarious, but hardly intuitive for the poor developer that made the change. A hallmark of loosely coupled code is that it&#8217;s upfront about its dependencies and behavior and is easy to modify and move around. <br /><br />Loose coupling, coherence and so on is really about design and architecture and is notoriously hard to measure. It really takes experience. One of the best ways to convey such experience is through code review, which we&#8217;ve already mentioned. Education on the SOLID principles, rules of thumb such as tell-don&#8217;t-ask, discussions about anti-patterns and code smells are all good here. Again, it&#8217;s hard to build tooling for this. You could write a presubmit check that forbids methods longer than 20 lines or cyclomatic complexity over 30, but that&#8217;s probably shooting yourself in the foot. Developers would consider that overbearing rather than a helpful assist. <br /><br />SETIs at Google are expected to give input on a product&#8217;s testability. A few well-placed test hooks in your product can enable tremendously powerful testing, such as serving mock content for apps (this enables you to meaningfully test app UI without contacting your real servers, for instance). Testability can also have an influence on architecture. For instance, it&#8217;s a testability problem if your servers are built like a huge monolith that is slow to build and start, or if it can&#8217;t boot on localhost without calling external services. We&#8217;ll cover this in the next article. <br /><h2>Aggressively Reduce Technical Debt</h2>It&#8217;s quite easy to add a lot of code and dependencies and call it a day when the software works. New projects can do this without many problems, but as the project becomes older it becomes a &#8220;legacy&#8221; project, weighed down by dependencies and excess code. Don&#8217;t end up there. It&#8217;s bad for hackability to have a slew of bug fixes stacked on top of unwise and obsolete decisions, and understanding and untangling the software becomes more difficult. <br /><br />What constitutes technical debt varies by project and is something you need to learn from experience. It simply means the software isn&#8217;t in optimal form. Some types of technical debt are easy to classify, such as dead code and barely-used dependencies. Some types are harder to identify, such as when the architecture of the project has grown unfit to the task from changing requirements. We can&#8217;t use tooling to help with the latter, but we can with the former. <br /><br />I already mentioned that <a href="https://cs.chromium.org/chromium/src/buildtools/checkdeps/builddeps.py?q=check_deps&#38;sq=package:chromium&#38;dr=C">dependency enforcement</a> can go a long way toward keeping people honest. It helps make sure people are making the appropriate trade-offs instead of just slapping on a new dependency, and it requires them to explain to a fellow engineer when they want to override a dependency rule. This can prevent unhealthy dependencies like circular dependencies, abstract modules depending on concrete modules, or modules depending on the internals of other modules. <br /><br />There are various tools available for visualizing dependency graphs as well. You can use these to get a grip on your current situation and start cleaning up dependencies. If you have a huge dependency you only use a small part of, maybe you can replace it with something simpler. If an old part of your app has inappropriate dependencies and other problems, maybe it&#8217;s time to rewrite that part. <br /><br /><div>(Continue to&#160;<a href="https://testing.googleblog.com/2016/10/hackable-projects-pillar-2-debuggability.html">Pillar 2: Debuggability</a>)</div>]]></description>
				<content:encoded><![CDATA[<em>By: Patrik Höglund </em><br /><h1>Introduction</h1>Software development is difficult. Projects often evolve over several years, under changing requirements and shifting market conditions, impacting developer tools and infrastructure. Technical debt, slow build systems, poor debuggability, and increasing numbers of dependencies can weigh down a project The developers get weary, and cobwebs accumulate in dusty corners of the code base. <br /><br />Fighting these issues can be taxing and feel like a quixotic undertaking, but don’t worry — the Google Testing Blog is riding to the rescue! This is the first article of a series on “hackability” that identifies some of the issues that hinder software projects and outlines what Google SETIs usually do about them. <br /><br /><a href="https://en.wiktionary.org/wiki/hackable">According to Wiktionary</a>, hackable is defined as: <br /><div style="border: 1px solid black; padding: 5px;"><b>Adjective</b><br /><b>hackable</b> ‎(comparative <b>more hackable</b>, superlative <b>most hackable</b>) <br /><ol><li>(computing) That can be hacked or broken into; insecure, vulnerable.&nbsp;</li><li>That lends itself to hacking (technical tinkering and modification); moddable.</li></ol></div><br />Obviously, we’re not going to talk about making your product more vulnerable (by, say, rolling your own crypto or something equally unwise); instead, we will focus on the second definition, which essentially means “something that is easy to work on.” This has become the <a href="http://googletesting.blogspot.com/2016/03/from-qa-to-engineering-productivity.html">mainfocus for SETIs at Google</a> as the role has evolved over the years.<br /><h2>In Practice</h2>In a hackable project, it’s easy to try things and hard to break things. Hackability means fast feedback cycles that offer useful information to the developer. <br /><br />This is hackability: <br /><ul><li>Developing is easy </li><li>Fast build </li><li>Good, fast tests </li><li>Clean code </li><li>Easy running + debugging </li><li>One-click rollbacks</li></ul>In contrast, what is not hackability? <br /><ul><li>Broken HEAD (tip-of-tree) </li><li>Slow presubmit (i.e. <a href="https://www.chromium.org/developers/how-tos/depottools/presubmit-scripts">checks running before submit</a>) </li><li>Builds take hours </li><li>Incremental build/link &gt; 30s </li><li><a href="http://googletesting.blogspot.com/2016/05/flaky-tests-at-google-and-how-we.html">Flakytests</a></li><li>Can’t attach debugger </li><li>Logs full of uninteresting information</li></ul><h2>The Three Pillars of Hackability</h2>There are a number of tools and practices that foster hackability. When everything is in place, it feels great to work on the product. Basically no time is spent on figuring out why things are broken, and all time is spent on what matters, which is understanding and working with the code. I believe there are three main pillars that support hackability. If one of them is absent, hackability will suffer. They are: <br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://3.bp.blogspot.com/-esLisB8th9M/V7XlS7pViVI/AAAAAAAAANs/lSJgkuiOF5w2Eqf1Yt_yaAbHqdwCYlg-gCLcB/s1600/image03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="203" src="https://3.bp.blogspot.com/-esLisB8th9M/V7XlS7pViVI/AAAAAAAAANs/lSJgkuiOF5w2Eqf1Yt_yaAbHqdwCYlg-gCLcB/s320/image03.png" width="320" /></a></div><br /><h1>Pillar 1: Code Health</h1><div style="border: 1px solid black; padding: 5px;">“I found Rome a city of bricks, and left it a city of marble.”<br />&nbsp; &nbsp;-- Augustus</div><br />Keeping the code in good shape is critical for hackability. It’s a lot harder to tinker and modify something if you don’t understand what it does (or if it’s full of hidden traps, for that matter). <br /><h2>Tests</h2>Unit and small integration tests are probably the best things you can do for hackability. They’re a support you can lean on while making your changes, and they contain lots of good information on what the code does. It isn’t hackability to boot a slow UI and click buttons on every iteration to verify your change worked - it is hackability to run a sub-second set of unit tests! In contrast, end-to-end (E2E) tests generally help hackability much less (and can <a href="http://googletesting.blogspot.com/2015/04/just-say-no-to-more-end-to-end-tests.html">evenbe a hindrance</a> if they, or the product, are in sufficiently bad shape). <br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://2.bp.blogspot.com/-H0OCdokbaVw/V7XlkhRcJcI/AAAAAAAAANw/z-v9qXyVig8dspmHHnRu6FQscqSOtvrTgCLcB/s1600/image01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="276" src="https://2.bp.blogspot.com/-H0OCdokbaVw/V7XlkhRcJcI/AAAAAAAAANw/z-v9qXyVig8dspmHHnRu6FQscqSOtvrTgCLcB/s320/image01.png" width="320" /></a></div><div style="text-align: center;"><em>Figure 1: the Testing Pyramid.</em></div><br />I’ve always been interested in how you actually make unit tests happen in a team. It’s about education. Writing a product such that it has good unit tests is actually a hard problem. It requires knowledge of dependency injection, testing/mocking frameworks, language idioms and refactoring. The difficulty varies by language as well. Writing unit tests in Go or Java is quite easy and natural, whereas in C++ it can be very difficult (and it isn’t exactly ingrained in C++ culture to write unit tests). <br /><br />It’s important to educate your developers about unit tests. Sometimes, it is appropriate to lead by example and help review unit tests as well. You can have a large impact on a project by establishing a pattern of unit testing early. If tons of code gets written without unit tests, it will be much harder to add unit tests later. <br /><br />What if you already have tons of poorly tested legacy code? The answer is refactoring and adding tests as you go. It’s hard work, but each line you add a test for is one more line that is easier to hack on. <br /><h2>Readable Code and Code Review</h2>At Google, “readability” is a special committer status that is granted per language (C++, Go, Java and so on). It means that a person not only knows the language and its culture and idioms well, but also can write clean, well tested and well structured code. Readability literally means that you’re a guardian of Google’s code base and should push back on hacky and ugly code. The use of a <a href="https://github.com/google/styleguide">style guide</a> enforces consistency, and <a href="https://en.wikipedia.org/wiki/Code_review">code review</a> (where at least one person with readability must approve) ensures the code upholds high quality. Engineers must take care to not depend too much on “review buddies” here but really make sure to pull in the person that can give the best feedback. <br /><br />Requiring code reviews naturally results in small changes, as reviewers often get grumpy if you dump huge changelists in their lap (at least if reviewers are somewhat fast to respond, which they should be). This is a good thing, since small changes are less risky and are easy to roll back. Furthermore, code review is good for knowledge sharing. You can also do pair programming if your team prefers that (a pair-programmed change is considered reviewed and can be submitted when both engineers are happy). There are multiple open-source review tools out there, such as <a href="https://www.gerritcodereview.com/">Gerrit</a>. <br /><br />Nice, clean code is great for hackability, since you don’t need to spend time to unwind that nasty pointer hack in your head before making your changes. How do you make all this happen in practice? Put together workshops on, say, the <a href="https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)">SOLID principles</a>, unit testing, or concurrency to encourage developers to learn. Spread knowledge through code review, pair programming and mentoring (such as with the Readability concept). You can’t just mandate higher code quality; it takes a lot of work, effort and consistency. <br /><h2>Presubmit Testing and Lint</h2>Consistently formatted source code aids hackability. You can scan code faster if its formatting is consistent. Automated tooling also aids hackability. It really doesn’t make sense to waste any time on formatting source code by hand. You should be using tools like <a href="https://golang.org/cmd/gofmt/">gofmt</a>, <a href="http://clang.llvm.org/docs/ClangFormat.html">clang-format</a>, etc. If the patch isn’t formatted properly, you should see something like this (<a href="https://cs.chromium.org/chromium/tools/depot_tools/presubmit_canned_checks.py?q=%22requires+formatting%22&amp;sq=package:chromium&amp;l=1151">example from Chrome</a>): <br /><br /><pre style="background: #f0f0f0; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;">$ git cl upload<br />Error: the media/audio directory requires formatting. Please run <br />    git cl format media/audio.</pre><br />Source formatting isn’t the only thing to check. In fact, you should check pretty much anything you have as a rule in your project. Should other modules not depend on the internals of your modules? <a href="https://cs.chromium.org/chromium/src/buildtools/checkdeps/builddeps.py?q=check_deps&amp;sq=package:chromium&amp;dr=C">Enforce it with a check</a>. Are there already inappropriate dependencies in your project? Whitelist the existing ones for now, but at least block new bad dependencies from forming. Should our app work on Android 16 phones and newer? <a href="https://bugs.chromium.org/p/webrtc/issues/detail?id=5063">Add linting</a>, so we don’t use level 17+ APIs without gating at runtime. Should your project’s <a href="https://en.wikipedia.org/wiki/VHDL">VHDL</a> code always place-and-route cleanly on a particular brand of <a href="https://en.wikipedia.org/wiki/Field-programmable_gate_array">FPGA</a>? Invoke the layout tool in your presubmit and and stop submit if the layout process fails. <br /><br />Presubmit is the most valuable real estate for aiding hackability. You have limited space in your presubmit, but you can get tremendous value out of it if you put the right things there. You should stop all obvious errors here. <br /><br />It aids hackability to have all this tooling so you don’t have to waste time going back and breaking things for other developers. Remember you need to maintain the presubmit well; it’s not hackability to have a slow, overbearing or buggy presubmit. Having a good presubmit can make it tremendously more pleasant to work on a project. We’re going to talk more in later articles on how to build infrastructure for submit queues and presubmit. <br /><h2>Single Branch And Reducing Risk</h2>Having a single branch for everything, and putting risky new changes behind <a href="https://en.wikipedia.org/wiki/Feature_toggle">feature flags</a>, aids hackability since branches and forks often amass tremendous risk when it’s time to merge them. Single branches smooth out the risk. Furthermore, running all your tests on many branches is expensive. However, a single branch can have negative effects on hackability if Team A depends on a library from Team B and gets broken by Team B a lot. Having some kind of stabilization on Team B’s software might be a good idea there. <a href="https://googletesting.blogspot.com/2015/05/multi-repository-development.html">Thisarticle</a> covers such situations, and how to integrate often with your dependencies to reduce the risk that one of them will break you. <br /><h2>Loose Coupling and Testability</h2>Tightly coupled code is terrible for hackability. To take the most ridiculous example I know: I once heard of a computer game where a developer changed a ballistics algorithm and broke the game’s <em>chat</em>. That’s hilarious, but hardly intuitive for the poor developer that made the change. A hallmark of loosely coupled code is that it’s upfront about its dependencies and behavior and is easy to modify and move around. <br /><br />Loose coupling, coherence and so on is really about design and architecture and is notoriously hard to measure. It really takes experience. One of the best ways to convey such experience is through code review, which we’ve already mentioned. Education on the SOLID principles, rules of thumb such as tell-don’t-ask, discussions about anti-patterns and code smells are all good here. Again, it’s hard to build tooling for this. You could write a presubmit check that forbids methods longer than 20 lines or cyclomatic complexity over 30, but that’s probably shooting yourself in the foot. Developers would consider that overbearing rather than a helpful assist. <br /><br />SETIs at Google are expected to give input on a product’s testability. A few well-placed test hooks in your product can enable tremendously powerful testing, such as serving mock content for apps (this enables you to meaningfully test app UI without contacting your real servers, for instance). Testability can also have an influence on architecture. For instance, it’s a testability problem if your servers are built like a huge monolith that is slow to build and start, or if it can’t boot on localhost without calling external services. We’ll cover this in the next article. <br /><h2>Aggressively Reduce Technical Debt</h2>It’s quite easy to add a lot of code and dependencies and call it a day when the software works. New projects can do this without many problems, but as the project becomes older it becomes a “legacy” project, weighed down by dependencies and excess code. Don’t end up there. It’s bad for hackability to have a slew of bug fixes stacked on top of unwise and obsolete decisions, and understanding and untangling the software becomes more difficult. <br /><br />What constitutes technical debt varies by project and is something you need to learn from experience. It simply means the software isn’t in optimal form. Some types of technical debt are easy to classify, such as dead code and barely-used dependencies. Some types are harder to identify, such as when the architecture of the project has grown unfit to the task from changing requirements. We can’t use tooling to help with the latter, but we can with the former. <br /><br />I already mentioned that <a href="https://cs.chromium.org/chromium/src/buildtools/checkdeps/builddeps.py?q=check_deps&amp;sq=package:chromium&amp;dr=C">dependency enforcement</a> can go a long way toward keeping people honest. It helps make sure people are making the appropriate trade-offs instead of just slapping on a new dependency, and it requires them to explain to a fellow engineer when they want to override a dependency rule. This can prevent unhealthy dependencies like circular dependencies, abstract modules depending on concrete modules, or modules depending on the internals of other modules. <br /><br />There are various tools available for visualizing dependency graphs as well. You can use these to get a grip on your current situation and start cleaning up dependencies. If you have a huge dependency you only use a small part of, maybe you can replace it with something simpler. If an old part of your app has inappropriate dependencies and other problems, maybe it’s time to rewrite that part. <br /><br /><div style="text-align: center;">(Continue to&nbsp;<a href="https://testing.googleblog.com/2016/10/hackable-projects-pillar-2-debuggability.html">Pillar 2: Debuggability</a>)</div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/hackable-projects/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>The Inquiry Method for Test Planning</title>
		<link>https://googledata.org/google-testing/the-inquiry-method-for-test-planning/</link>
		<comments>https://googledata.org/google-testing/the-inquiry-method-for-test-planning/#comments</comments>
		<pubDate>Mon, 06 Jun 2016 13:05:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=06e9c37addfafbb13bffb6c093d14f2a</guid>
		<description><![CDATA[<i>by <a href="http://anthonyvallone.com/">Anthony Vallone</a></i><br /><div><i>updated: July 2016</i></div><br /><br /><br /><br /><div>Creating a test plan is often a complex undertaking. An ideal test plan is accomplished by applying basic principles of <a href="https://en.wikipedia.org/wiki/Cost%E2%80%93benefit_analysis">cost-benefit analysis</a> and <a href="https://en.wikipedia.org/wiki/Risk_analysis">risk analysis</a>, optimally balancing these software development factors:</div><div><ul><li><b>Implementation cost</b>: The time and complexity of implementing testable features and automated tests for specific scenarios will vary, and this affects short-term development cost.</li><li><b>Maintenance cost</b>: Some tests or test plans may vary from easy to difficult to maintain, and this affects long-term development cost. When manual testing is chosen, this also adds to long-term cost.</li><li><b>Monetary cost</b>: Some test approaches may require billed resources.</li><li><b>Benefit</b>: Tests are capable of preventing issues and aiding productivity by varying degrees. Also, the earlier they can catch problems in the development life-cycle, the greater the benefit.</li><li><b>Risk</b>: The probability of failure scenarios may vary from rare to likely, and their consequences may vary from minor nuisance to catastrophic.</li></ul></div><div>Effectively balancing these factors in a plan depends heavily on project criticality, implementation details, resources available, and team opinions. Many projects can achieve outstanding coverage with high-benefit, low-cost unit tests, but they may need to weigh options for larger tests and complex corner cases. Mission critical projects must minimize risk as much as possible, so they will accept higher costs and invest heavily in rigorous testing at all levels.</div><div><br /></div><div>This guide puts the onus on the reader to find the right balance for their project. Also, it does not provide a test plan template, because templates are often too generic or too specific and quickly become outdated. Instead, it focuses on selecting the best content when writing a test plan.</div><div><br /><br /></div><div><h3>Test plan vs. strategy</h3><div><br />Before proceeding, two common methods for defining test plans need to be clarified:</div><div><ul><li><b>Single test plan</b>: Some projects have a single "test plan" that describes all implemented and planned testing for the project.</li><li><b>Single test strategy and many plans</b>: Some projects have a "test strategy" document as well as many smaller "test plan" documents. Strategies typically cover the overall test approach and goals, while plans cover specific features or project updates.</li></ul></div><div>Either of these may be embedded in and integrated with project design documents. Both of these methods work well, so choose whichever makes sense for your project. Generally speaking, stable projects benefit from a single plan, whereas rapidly changing projects are best served by infrequently changed strategies and frequently added plans.</div><div><br /></div><div>For the purpose of this guide, I will refer to both test document types simply as "test plans&#8221;. If you have multiple documents, just apply the advice below to your document aggregation.</div></div><div><br /><br /></div><div><h3>Content selection</h3><div><br />A good approach to creating content for your test plan is to start by listing all questions that need answers. The lists below provide a comprehensive collection of important questions that may or may not apply to your project. Go through the lists and select all that apply. By answering these questions, you will form the contents for your test plan, and you should structure your plan around the chosen content in any format your team prefers. Be sure to balance the factors as mentioned above when making decisions.</div></div><div><br /><br /></div><div><h3>Prerequisites</h3><div><br /></div><div><ul><li><b>Do you need a test plan?</b> If there is no project design document or a clear vision for the product, it may be too early to write a test plan.</li><li><b>Has testability been considered in the project design?</b> Before a project gets too far into implementation, all scenarios must be designed as testable, preferably via automation. Both project design documents and test plans should comment on testability as needed.</li><li><b>Will you keep the plan up-to-date?</b> If so, be careful about adding too much detail, otherwise it may be difficult to maintain the plan.</li><li><b>Does this quality effort overlap with other teams?</b> If so, how have you deduplicated the work?</li></ul></div></div><div><br /></div><div><h3>Risk</h3><div><br /></div><div><ul><li><b>Are there any significant project risks, and how will you mitigate them?</b> Consider: <ul><li>Injury to people or animals</li><li>Security and integrity of user data</li><li>User privacy</li><li>Security of company systems</li><li>Hardware or property damage</li><li>Legal and compliance issues</li><li>Exposure of confidential or sensitive data</li><li>Data loss or corruption</li><li>Revenue loss</li><li>Unrecoverable scenarios</li><li>SLAs</li><li>Performance requirements</li><li>Misinforming users</li><li>Impact to other projects</li><li>Impact from other projects</li><li>Impact to company&#8217;s public image</li><li>Loss of productivity</li></ul></li><li><b>What are the project&#8217;s technical vulnerabilities?</b> Consider: <ul><li>Features or components known to be hacky, fragile, or in great need of refactoring</li><li>Dependencies or platforms that frequently cause issues</li><li>Possibility for users to cause harm to the system</li><li>Trends seen in past issues</li></ul></li></ul></div></div><div><br /><h3>Coverage</h3><div><br /></div><ul><li><b>What does the test surface look like?</b> Is it a simple library with one method, or a multi-platform client-server stateful system with a combinatorial explosion of use cases? Describe the design and architecture of the system in a way that highlights possible points of failure.</li><li><b>What platforms are supported?</b> Consider listing supported operating systems, hardware, devices, etc. Also describe how testing will be performed and reported for each platform.</li><li><b>What are the features?</b> Consider making a summary list of all features and describe how certain categories of features will be tested.</li><li><b>What will not be tested?</b> No test suite covers every possibility. It&#8217;s best to be up-front about this and provide rationale for not testing certain cases. Examples: low risk areas that are a low priority, complex cases that are a low priority, areas covered by other teams, features not ready for testing, etc.&#160;</li><li><b>What is covered by unit (small), integration (medium), and system (large) tests?</b> Always test as much as possible in smaller tests, leaving fewer cases for larger tests. Describe how certain categories of test cases are best tested by each test size and provide rationale.</li><li><b>What will be tested manually vs. automated?</b> When feasible and cost-effective, automation is usually best. Many projects can automate all testing. However, there may be good reasons to choose manual testing. Describe the types of cases that will be tested manually and provide rationale.</li><li><b>How are you covering each test category?</b> Consider: <ul><li><a href="http://www.w3.org/wiki/Accessibility_testing">accessibility</a></li><li><a href="http://en.wikipedia.org/wiki/Functional_testing">functional</a></li><li><a href="http://en.wikipedia.org/wiki/Fuzz_testing">fuzz</a></li><li>internationalization and localization</li><li><a href="http://en.wikipedia.org/wiki/Software_performance_testing">performance</a>, <a href="http://en.wikipedia.org/wiki/Load_testing">load</a>, <a href="http://en.wikipedia.org/wiki/Stress_testing">stress</a>, and <a href="https://en.wikipedia.org/wiki/Soak_testing">endurance</a> (aka soak)</li><li>privacy</li><li><a href="http://en.wikipedia.org/wiki/Security_testing">security</a></li><li><a href="http://en.wikipedia.org/wiki/Smoke_testing_(software)">smoke</a></li><li><a href="http://en.wikipedia.org/wiki/Stability_testing">stability</a></li><li><a href="http://en.wikipedia.org/wiki/Usability_testing">usability</a></li></ul></li><li><b>Will you use static and/or dynamic analysis tools?</b> Both <a href="https://en.wikipedia.org/wiki/Static_program_analysis">static analysis tools</a> and <a href="https://en.wikipedia.org/wiki/Dynamic_program_analysis">dynamic analysis tools</a> can find problems that are hard to catch in reviews and testing, so consider using them.</li><li><b>How will system components and dependencies be stubbed, mocked, faked, staged, or used normally during testing?</b> There are good reasons to do each of these, and they each have a unique impact on coverage.</li><li><b>What builds are your tests running against?</b> Are tests running against a build from HEAD (aka tip), a staged build, and/or a release candidate? If only from HEAD, how will you test release build cherry picks (selection of individual changelists for a release) and system configuration changes not normally seen by builds from HEAD?</li><li><b>What kind of testing will be done outside of your team?</b> Examples: <ul><li><a href="https://en.wikipedia.org/wiki/Eating_your_own_dog_food">Dogfooding</a></li><li>External crowdsource testing</li><li>Public alpha/beta versions (how will they be tested before releasing?)</li><li>External trusted testers</li></ul></li><li><b>How are data migrations tested?</b> You may need special testing to compare before and after migration results.</li><li><b>Do you need to be concerned with backward compatibility?</b> You may own previously distributed clients or there may be other systems that depend on your system&#8217;s protocol, configuration, features, and behavior.</li><li><b>Do you need to test upgrade scenarios for server/client/device software or dependencies/platforms/APIs that the software utilizes?</b></li><li><b>Do you have line coverage goals?</b></li></ul></div><div><br /><h3>Tooling and Infrastructure</h3><div><br /></div><ul><li><b>Do you need new test frameworks?</b> If so, describe these or add design links in the plan.</li><li><b>Do you need a new test lab setup?</b> If so, describe these or add design links in the plan.</li><li><b>If your project offers a service to other projects, are you providing test tools to those users?</b> Consider providing mocks, fakes, and/or reliable staged servers for users trying to test their integration with your system.</li><li><b>For end-to-end testing, how will test infrastructure, systems under test, and other dependencies be managed?</b> How will they be deployed? How will persistence be set-up/torn-down? How will you handle required migrations from one datacenter to another?</li><li><b>Do you need tools to help debug system or test failures? </b>You may be able to use existing tools, or you may need to develop new ones.</li></ul><br /><h3>Process</h3><div><br /></div><ul><li><b>Are there test schedule requirements? </b>What time commitments have been made, which tests will be in place (or test feedback provided) by what dates? Are some tests important to deliver before others?</li><li><b>How are builds and tests run continuously?</b> Most small tests will be run by <a href="https://en.wikipedia.org/wiki/Continuous_integration">continuous integration</a> tools, but large tests may need a different approach. Alternatively, you may opt for running large tests as-needed.&#160;</li><li><b>How will build and test results be reported and monitored? </b><ul><li>Do you have a team rotation to monitor continuous integration?</li><li>Large tests might require monitoring by someone with expertise.</li><li>Do you need a dashboard for test results and other project health indicators?</li><li>Who will get email alerts and how?</li><li>Will the person monitoring tests simply use verbal communication to the team?</li></ul></li><li><b>How are tests used when releasing? </b><ul><li>Are they run explicitly against the release candidate, or does the release process depend only on continuous test results?&#160;</li><li>If system components and dependencies are released independently, are tests run for each type of release?&#160;</li><li>Will a "release blocker" bug stop the release manager(s) from actually releasing? Is there an agreement on what are the release blocking criteria?</li><li>When performing canary releases (aka % rollouts), how will progress be monitored and tested?</li></ul></li><li><b>How will external users report bugs?</b> Consider feedback links or other similar tools to collect and cluster reports.</li><li><b>How does bug triage work? </b>Consider labels or categories for bugs in order for them to land in a triage bucket. Also make sure the teams responsible for filing and or creating the bug report template are aware of this. Are you using one bug tracker or do you need to setup some automatic or manual import routine?</li><li><b>Do you have a policy for submitting new tests before closing bugs that could have been caught?</b></li><li><b>How are tests used for unsubmitted changes?</b> If anyone can run all tests against any experimental build (a good thing), consider providing a howto.</li><li><b>How can team members create and/or debug tests?</b> Consider providing a howto.</li></ul><br /><h3>Utility</h3><div><br /></div><ul><li><b>Who are the test plan readers?</b> Some test plans are only read by a few people, while others are read by many. At a minimum, you should consider getting a review from all stakeholders (project managers, tech leads, feature owners). When writing the plan, be sure to understand the expected readers, provide them with enough background to understand the plan, and answer all questions you think they will have - even if your answer is that you don&#8217;t have an answer yet. Also consider adding contacts for the test plan, so any reader can get more information.</li><li><b>How can readers review the actual test cases?</b> Manual cases might be in a test case management tool, in a separate document, or included in the test plan. Consider providing links to directories containing automated test cases.</li><li><b>Do you need traceability between requirements, features, and tests?</b></li><li><b>Do you have any general product health or quality goals and how will you measure success?</b> Consider: <ul><li>Release cadence</li><li>Number of bugs caught by users in production</li><li>Number of bugs caught in release testing</li><li>Number of open bugs over time</li><li>Code coverage</li><li>Cost of manual testing</li><li>Difficulty of creating new tests</li></ul></li></ul></div><br /><br />]]></description>
				<content:encoded><![CDATA[<i>by <a href="http://anthonyvallone.com/">Anthony Vallone</a></i><br /><div style="text-align: center;"><i>updated: July 2016</i></div><br /><br /><br /><br /><div>Creating a test plan is often a complex undertaking. An ideal test plan is accomplished by applying basic principles of <a href="https://en.wikipedia.org/wiki/Cost%E2%80%93benefit_analysis">cost-benefit analysis</a> and <a href="https://en.wikipedia.org/wiki/Risk_analysis">risk analysis</a>, optimally balancing these software development factors:</div><div><ul><li><b>Implementation cost</b>: The time and complexity of implementing testable features and automated tests for specific scenarios will vary, and this affects short-term development cost.</li><li><b>Maintenance cost</b>: Some tests or test plans may vary from easy to difficult to maintain, and this affects long-term development cost. When manual testing is chosen, this also adds to long-term cost.</li><li><b>Monetary cost</b>: Some test approaches may require billed resources.</li><li><b>Benefit</b>: Tests are capable of preventing issues and aiding productivity by varying degrees. Also, the earlier they can catch problems in the development life-cycle, the greater the benefit.</li><li><b>Risk</b>: The probability of failure scenarios may vary from rare to likely, and their consequences may vary from minor nuisance to catastrophic.</li></ul></div><div>Effectively balancing these factors in a plan depends heavily on project criticality, implementation details, resources available, and team opinions. Many projects can achieve outstanding coverage with high-benefit, low-cost unit tests, but they may need to weigh options for larger tests and complex corner cases. Mission critical projects must minimize risk as much as possible, so they will accept higher costs and invest heavily in rigorous testing at all levels.</div><div><br /></div><div>This guide puts the onus on the reader to find the right balance for their project. Also, it does not provide a test plan template, because templates are often too generic or too specific and quickly become outdated. Instead, it focuses on selecting the best content when writing a test plan.</div><div><br /><br /></div><div><h3>Test plan vs. strategy</h3><div><br />Before proceeding, two common methods for defining test plans need to be clarified:</div><div><ul><li><b>Single test plan</b>: Some projects have a single "test plan" that describes all implemented and planned testing for the project.</li><li><b>Single test strategy and many plans</b>: Some projects have a "test strategy" document as well as many smaller "test plan" documents. Strategies typically cover the overall test approach and goals, while plans cover specific features or project updates.</li></ul></div><div>Either of these may be embedded in and integrated with project design documents. Both of these methods work well, so choose whichever makes sense for your project. Generally speaking, stable projects benefit from a single plan, whereas rapidly changing projects are best served by infrequently changed strategies and frequently added plans.</div><div><br /></div><div>For the purpose of this guide, I will refer to both test document types simply as "test plans”. If you have multiple documents, just apply the advice below to your document aggregation.</div></div><div><br /><br /></div><div><h3>Content selection</h3><div><br />A good approach to creating content for your test plan is to start by listing all questions that need answers. The lists below provide a comprehensive collection of important questions that may or may not apply to your project. Go through the lists and select all that apply. By answering these questions, you will form the contents for your test plan, and you should structure your plan around the chosen content in any format your team prefers. Be sure to balance the factors as mentioned above when making decisions.</div></div><div><br /><br /></div><div><h3>Prerequisites</h3><div><br /></div><div><ul><li><b>Do you need a test plan?</b> If there is no project design document or a clear vision for the product, it may be too early to write a test plan.</li><li><b>Has testability been considered in the project design?</b> Before a project gets too far into implementation, all scenarios must be designed as testable, preferably via automation. Both project design documents and test plans should comment on testability as needed.</li><li><b>Will you keep the plan up-to-date?</b> If so, be careful about adding too much detail, otherwise it may be difficult to maintain the plan.</li><li><b>Does this quality effort overlap with other teams?</b> If so, how have you deduplicated the work?</li></ul></div></div><div><br /></div><div><h3>Risk</h3><div><br /></div><div><ul><li><b>Are there any significant project risks, and how will you mitigate them?</b> Consider: <ul><li>Injury to people or animals</li><li>Security and integrity of user data</li><li>User privacy</li><li>Security of company systems</li><li>Hardware or property damage</li><li>Legal and compliance issues</li><li>Exposure of confidential or sensitive data</li><li>Data loss or corruption</li><li>Revenue loss</li><li>Unrecoverable scenarios</li><li>SLAs</li><li>Performance requirements</li><li>Misinforming users</li><li>Impact to other projects</li><li>Impact from other projects</li><li>Impact to company’s public image</li><li>Loss of productivity</li></ul></li><li><b>What are the project’s technical vulnerabilities?</b> Consider: <ul><li>Features or components known to be hacky, fragile, or in great need of refactoring</li><li>Dependencies or platforms that frequently cause issues</li><li>Possibility for users to cause harm to the system</li><li>Trends seen in past issues</li></ul></li></ul></div></div><div><br /><h3>Coverage</h3><div><br /></div><ul><li><b>What does the test surface look like?</b> Is it a simple library with one method, or a multi-platform client-server stateful system with a combinatorial explosion of use cases? Describe the design and architecture of the system in a way that highlights possible points of failure.</li><li><b>What platforms are supported?</b> Consider listing supported operating systems, hardware, devices, etc. Also describe how testing will be performed and reported for each platform.</li><li><b>What are the features?</b> Consider making a summary list of all features and describe how certain categories of features will be tested.</li><li><b>What will not be tested?</b> No test suite covers every possibility. It’s best to be up-front about this and provide rationale for not testing certain cases. Examples: low risk areas that are a low priority, complex cases that are a low priority, areas covered by other teams, features not ready for testing, etc.&nbsp;</li><li><b>What is covered by unit (small), integration (medium), and system (large) tests?</b> Always test as much as possible in smaller tests, leaving fewer cases for larger tests. Describe how certain categories of test cases are best tested by each test size and provide rationale.</li><li><b>What will be tested manually vs. automated?</b> When feasible and cost-effective, automation is usually best. Many projects can automate all testing. However, there may be good reasons to choose manual testing. Describe the types of cases that will be tested manually and provide rationale.</li><li><b>How are you covering each test category?</b> Consider: <ul><li><a href="http://www.w3.org/wiki/Accessibility_testing">accessibility</a></li><li><a href="http://en.wikipedia.org/wiki/Functional_testing">functional</a></li><li><a href="http://en.wikipedia.org/wiki/Fuzz_testing">fuzz</a></li><li>internationalization and localization</li><li><a href="http://en.wikipedia.org/wiki/Software_performance_testing">performance</a>, <a href="http://en.wikipedia.org/wiki/Load_testing">load</a>, <a href="http://en.wikipedia.org/wiki/Stress_testing">stress</a>, and <a href="https://en.wikipedia.org/wiki/Soak_testing">endurance</a> (aka soak)</li><li>privacy</li><li><a href="http://en.wikipedia.org/wiki/Security_testing">security</a></li><li><a href="http://en.wikipedia.org/wiki/Smoke_testing_(software)">smoke</a></li><li><a href="http://en.wikipedia.org/wiki/Stability_testing">stability</a></li><li><a href="http://en.wikipedia.org/wiki/Usability_testing">usability</a></li></ul></li><li><b>Will you use static and/or dynamic analysis tools?</b> Both <a href="https://en.wikipedia.org/wiki/Static_program_analysis">static analysis tools</a> and <a href="https://en.wikipedia.org/wiki/Dynamic_program_analysis">dynamic analysis tools</a> can find problems that are hard to catch in reviews and testing, so consider using them.</li><li><b>How will system components and dependencies be stubbed, mocked, faked, staged, or used normally during testing?</b> There are good reasons to do each of these, and they each have a unique impact on coverage.</li><li><b>What builds are your tests running against?</b> Are tests running against a build from HEAD (aka tip), a staged build, and/or a release candidate? If only from HEAD, how will you test release build cherry picks (selection of individual changelists for a release) and system configuration changes not normally seen by builds from HEAD?</li><li><b>What kind of testing will be done outside of your team?</b> Examples: <ul><li><a href="https://en.wikipedia.org/wiki/Eating_your_own_dog_food">Dogfooding</a></li><li>External crowdsource testing</li><li>Public alpha/beta versions (how will they be tested before releasing?)</li><li>External trusted testers</li></ul></li><li><b>How are data migrations tested?</b> You may need special testing to compare before and after migration results.</li><li><b>Do you need to be concerned with backward compatibility?</b> You may own previously distributed clients or there may be other systems that depend on your system’s protocol, configuration, features, and behavior.</li><li><b>Do you need to test upgrade scenarios for server/client/device software or dependencies/platforms/APIs that the software utilizes?</b></li><li><b>Do you have line coverage goals?</b></li></ul></div><div><br /><h3>Tooling and Infrastructure</h3><div><br /></div><ul><li><b>Do you need new test frameworks?</b> If so, describe these or add design links in the plan.</li><li><b>Do you need a new test lab setup?</b> If so, describe these or add design links in the plan.</li><li><b>If your project offers a service to other projects, are you providing test tools to those users?</b> Consider providing mocks, fakes, and/or reliable staged servers for users trying to test their integration with your system.</li><li><b>For end-to-end testing, how will test infrastructure, systems under test, and other dependencies be managed?</b> How will they be deployed? How will persistence be set-up/torn-down? How will you handle required migrations from one datacenter to another?</li><li><b>Do you need tools to help debug system or test failures? </b>You may be able to use existing tools, or you may need to develop new ones.</li></ul><br /><h3>Process</h3><div><br /></div><ul><li><b>Are there test schedule requirements? </b>What time commitments have been made, which tests will be in place (or test feedback provided) by what dates? Are some tests important to deliver before others?</li><li><b>How are builds and tests run continuously?</b> Most small tests will be run by <a href="https://en.wikipedia.org/wiki/Continuous_integration">continuous integration</a> tools, but large tests may need a different approach. Alternatively, you may opt for running large tests as-needed.&nbsp;</li><li><b>How will build and test results be reported and monitored? </b><ul><li>Do you have a team rotation to monitor continuous integration?</li><li>Large tests might require monitoring by someone with expertise.</li><li>Do you need a dashboard for test results and other project health indicators?</li><li>Who will get email alerts and how?</li><li>Will the person monitoring tests simply use verbal communication to the team?</li></ul></li><li><b>How are tests used when releasing? </b><ul><li>Are they run explicitly against the release candidate, or does the release process depend only on continuous test results?&nbsp;</li><li>If system components and dependencies are released independently, are tests run for each type of release?&nbsp;</li><li>Will a "release blocker" bug stop the release manager(s) from actually releasing? Is there an agreement on what are the release blocking criteria?</li><li>When performing canary releases (aka % rollouts), how will progress be monitored and tested?</li></ul></li><li><b>How will external users report bugs?</b> Consider feedback links or other similar tools to collect and cluster reports.</li><li><b>How does bug triage work? </b>Consider labels or categories for bugs in order for them to land in a triage bucket. Also make sure the teams responsible for filing and or creating the bug report template are aware of this. Are you using one bug tracker or do you need to setup some automatic or manual import routine?</li><li><b>Do you have a policy for submitting new tests before closing bugs that could have been caught?</b></li><li><b>How are tests used for unsubmitted changes?</b> If anyone can run all tests against any experimental build (a good thing), consider providing a howto.</li><li><b>How can team members create and/or debug tests?</b> Consider providing a howto.</li></ul><br /><h3>Utility</h3><div><br /></div><ul><li><b>Who are the test plan readers?</b> Some test plans are only read by a few people, while others are read by many. At a minimum, you should consider getting a review from all stakeholders (project managers, tech leads, feature owners). When writing the plan, be sure to understand the expected readers, provide them with enough background to understand the plan, and answer all questions you think they will have - even if your answer is that you don’t have an answer yet. Also consider adding contacts for the test plan, so any reader can get more information.</li><li><b>How can readers review the actual test cases?</b> Manual cases might be in a test case management tool, in a separate document, or included in the test plan. Consider providing links to directories containing automated test cases.</li><li><b>Do you need traceability between requirements, features, and tests?</b></li><li><b>Do you have any general product health or quality goals and how will you measure success?</b> Consider: <ul><li>Release cadence</li><li>Number of bugs caught by users in production</li><li>Number of bugs caught in release testing</li><li>Number of open bugs over time</li><li>Code coverage</li><li>Cost of manual testing</li><li>Difficulty of creating new tests</li></ul></li></ul></div><br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/the-inquiry-method-for-test-planning/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>GTAC 2016 Registration Deadline Extended</title>
		<link>https://googledata.org/google-testing/gtac-2016-registration-deadline-extended/</link>
		<comments>https://googledata.org/google-testing/gtac-2016-registration-deadline-extended/#comments</comments>
		<pubDate>Fri, 03 Jun 2016 03:58:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=f993a359737758ed8f4c06d9b81f1f70</guid>
		<description><![CDATA[by Sonal Shah on behalf of the GTAC CommitteeOur goal in organizing GTAC each year is to make it a first-class conference, dedicated to presenting leading edge industry practices. The quality of submissions we've received for GTAC 2016 so far has been ...]]></description>
				<content:encoded><![CDATA[<i>by Sonal Shah on behalf of the GTAC Committee</i><br /><br />Our goal in organizing GTAC each year is to make it a first-class conference, dedicated to presenting leading edge industry practices. The quality of submissions we've received for GTAC 2016 so far has been overwhelming. In order to include the best talks possible, we are extending the deadline for speaker and attendee submissions by 15 days. The new timelines are as follows:<br /><br /><strike>June 1, 2016</strike> <b>June 15, 2016</b> - Last day for speaker, attendee and diversity scholarship submissions.<br /><strike>June 15, 2016</strike> <b>July 15, 2016</b> - Attendees and scholarship awardees will be notified of selection/rejection/waitlist status. Those on the waitlist will be notified as space becomes available.<br /><strike>August 15, 2016</strike> <b>August 29, 2016</b> - Selected speakers will be notified.<br /><br />To register, please fill out <a href="https://docs.google.com/a/google.com/forms/d/1gT3jZtP03a38zaJ6gFUXb74PW6MugustSem938UWv3c/viewform">this</a> form.<br />To apply for diversity scholarship, please fill out <a href="https://docs.google.com/a/google.com/forms/d/1PozpfkbSH3YX_BVbXRhju5jkZNy-gGcs45dnKIvIEsE/edit?usp=sharing">this</a> form.<br /><br />The <a href="https://developers.google.com/google-test-automation-conference/2016/faq-conference">GTAC website</a> has a list of frequently asked questions. Please do not hesitate to contact <a href="mailto:gtac2016@google.com">gtac2016@google.com</a> if you still have any questions.<br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/gtac-2016-registration-deadline-extended/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Flaky Tests at Google and How We Mitigate Them</title>
		<link>https://googledata.org/google-testing/flaky-tests-at-google-and-how-we-mitigate-them/</link>
		<comments>https://googledata.org/google-testing/flaky-tests-at-google-and-how-we-mitigate-them/#comments</comments>
		<pubDate>Sat, 28 May 2016 00:31:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=b651c219e977eff6fcba7d5cd09baba1</guid>
		<description><![CDATA[by John MiccoAt Google, we run a very large corpus of tests continuously to validate our code submissions. Everyone from developers to project managers rely on the results of these tests to make decisions about whether the system is ready for deploymen...]]></description>
				<content:encoded><![CDATA[<i>by John Micco</i><br /><br />At Google, we run a very large corpus of tests continuously to validate our code submissions. Everyone from developers to project managers rely on the results of these tests to make decisions about whether the system is ready for deployment or whether code changes are OK to submit. Productivity for developers at Google relies on the ability of the tests to find real problems with the code being changed or developed in a timely and reliable fashion. <br /><br />Tests are run before submission (pre-submit testing) which gates submission and verifies that changes are acceptable, and again after submission (post-submit testing) to decide whether the project is ready to be released. In both cases, all of the tests for a particular project must report a passing result before submitting code or releasing a project.<br /><br />Unfortunately, across our entire corpus of tests, we see a continual rate of about 1.5% of all test runs reporting a "flaky" result. We define a "flaky" test result as a test that exhibits both a passing and a failing result with the same code. There are many <a href="http://www.cs.umd.edu/~atif/pubs/gao-icse15.pdf">root causes</a> why tests return flaky results, including concurrency, relying on non-deterministic or undefined behaviors, flaky third party code, infrastructure problems, etc. We have invested a lot of effort in removing flakiness from tests, but overall the insertion rate is about the same as the fix rate, meaning we are stuck with a certain rate of tests that provide value, but occasionally produce a flaky result. Almost 16% of our tests have some level of flakiness associated with them! This is a staggering number; it means that more than 1 in 7 of the tests written by our world-class engineers occasionally fail in a way not caused by changes to the code or tests.<br /><br />When doing post-submit testing, our Continuous Integration (CI) system identifies when a passing test transitions to failing, so that we can investigate the code submission that caused the failure. What we find in practice is that about 84% of the transitions we observe from pass to fail involve a flaky test! This causes extra repetitive work to determine whether a new failure is a flaky result or a legitimate failure. It is quite common to ignore legitimate failures in flaky tests due to the high number of false-positives. At the very least, build monitors typically wait for additional CI cycles to run this test again to determine whether or not the test has been broken by a submission adding to the delay of identifying real problems and increasing the pool of changes that could contribute.<br /><br />In addition to the cost of build monitoring, consider that the average project contains 1000 or so individual tests. To release a project, we require that all these tests pass with the latest code changes. If 1.5% of test results are flaky, 15 tests will likely fail, requiring expensive investigation by a build cop or developer. In some cases, developers dismiss a failing result as flaky only to later realize that it was a legitimate failure caused by the code. It is human nature to ignore alarms when there is a history of false signals coming from a system. For example, see <a href="http://www.travelweekly.com/Travel-News/Airline-News/Analysis-shows-pilots-often-ignore-Boeing-737-cockpit-alarm">this article</a> about airline pilots ignoring an alarm on 737s. The same phenomenon occurs with pre-submit testing.  The same 15 or so failing tests block submission and introduce costly delays into the core development process. Ignoring legitimate failures at this stage results in the submission of broken code.<br /><br />We have several mitigation strategies for flaky tests during presubmit testing, including the ability to re-run only failing tests, and an option to re-run tests automatically when they fail. We even have a way to denote a test as flaky - causing it to report a failure only if it fails 3 times in a row. This reduces false positives, but encourages developers to ignore flakiness in their own tests unless their tests start failing 3 times in a row, which is hardly a perfect solution.<br />Imagine a 15 minute integration test marked as flaky that is broken by my code submission. The breakage will not be discovered until 3 executions of the test complete, or 45 minutes, after which it will need to be determined if the test is broken (and needs to be fixed) or if the test just flaked three times in a row.<br /><br />Other mitigation strategies include:<br /><ul><li>A tool that monitors the flakiness of tests and if the flakiness is too high, it automatically quarantines the test. Quarantining removes the test from the critical path and files a bug for developers to reduce the flakiness. This prevents it from becoming a problem for developers, but could easily mask a real race condition or some other bug in the code being tested.</li><li>Another tool detects changes in the flakiness level of tests and works to identify the change that caused the test to change the level of flakiness.</li></ul><br />In summary, test flakiness is an important problem, and Google is continuing to invest in detecting, mitigating, tracking, and fixing test flakiness throughout our code base. For example:<br /><ul><li>We have a new team dedicated to providing accurate and timely information about test flakiness to help developers and build monitors so that they know whether they are being harmed by test flakiness.</li><li>As we analyze the data from flaky test executions, we are seeing promising correlations with features that should enable us to identify a flaky result accurately without re-running the test.</li></ul><br /><br />By continually advancing the state of the art for teams at Google, we aim to remove the friction caused by test flakiness from the core developer workflows.<br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/flaky-tests-at-google-and-how-we-mitigate-them/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>GTAC Diversity Scholarship</title>
		<link>https://googledata.org/google-testing/gtac-diversity-scholarship/</link>
		<comments>https://googledata.org/google-testing/gtac-diversity-scholarship/#comments</comments>
		<pubDate>Wed, 04 May 2016 14:32:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=c3102e9d34c77fd4dadd6cd27231a327</guid>
		<description><![CDATA[by Lesley Katzen on behalf of the GTAC Diversity CommitteeWe are committed to increasing diversity at GTAC, and we believe the best way to do that is by making sure we have a diverse set of applicants to speak and attend. As part of that commitment, we...]]></description>
				<content:encoded><![CDATA[<i>by Lesley Katzen on behalf of the GTAC Diversity Committee</i><br /><br />We are committed to increasing diversity at GTAC, and we believe the best way to do that is by making sure we have a diverse set of applicants to speak and attend. As part of that commitment, we are excited to announce that we will be offering travel scholarships this year.<br />Travel scholarships will be available for selected applicants from traditionally underrepresented groups in technology.<br /><br />To be eligible for a grant to attend GTAC, applicants must:<br /><br /><ul><li>Be 18 years of age or older.</li><li>Be from a traditionally underrepresented group in technology.</li><li>Work or study in Computer Science, Computer Engineering, Information Technology, or a technical field related to software testing.</li><li>Be able to attend core dates of GTAC, November 15th - 16th 2016 in Sunnyvale, CA.</li></ul><br /><br /><b>To apply:</b><br />Please fill out the following <a href="https://docs.google.com/a/google.com/forms/d/1PozpfkbSH3YX_BVbXRhju5jkZNy-gGcs45dnKIvIEsE/edit?usp=sharing">form</a> to be considered for a travel scholarship.<br />The deadline for submission is <strike>June 1st</strike> June 15th. &nbsp;Scholarship recipients will be announced on <strike>June 30th</strike> July 15th. If you are selected, we will contact you with information on how to proceed with booking travel.<br /><br /><br /><b>What the scholarship covers:</b><br />Google will pay for standard coach class airfare for selected scholarship recipients to San Francisco or San Jose, and 3 nights of accommodations in a hotel near the Sunnyvale campus. Breakfast and lunch will be provided for GTAC attendees and speakers on both days of the conference. We will also provide a $50.00 gift card for other incidentals such as airport transportation or meals. You will need to provide your own credit card to cover any hotel incidentals.<br /><br /><br />Google is dedicated to providing a harassment-free and inclusive conference experience for everyone. Our anti-harassment policy can be found at:<br /><a href="https://www.google.com/events/policy/anti-harassmentpolicy.html">https://www.google.com/events/policy/anti-harassmentpolicy.html</a>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/gtac-diversity-scholarship/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>GTAC 2016 Registration is now open!</title>
		<link>https://googledata.org/google-testing/gtac-2016-registration-is-now-open/</link>
		<comments>https://googledata.org/google-testing/gtac-2016-registration-is-now-open/#comments</comments>
		<pubDate>Wed, 04 May 2016 14:27:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=5b62bf7f3bc4a74e3ab3ba8d784398b6</guid>
		<description><![CDATA[by Sonal Shah on behalf of the GTAC CommitteeThe GTAC (Google Test Automation Conference) 2016 application process is now open for presentation proposals and attendance. GTAC will be held at the Google Sunnyvale office on November 15th - 16th, 2016.GTA...]]></description>
				<content:encoded><![CDATA[<i>by Sonal Shah on behalf of the GTAC Committee</i><br /><br />The GTAC (Google Test Automation Conference) 2016 application process is now open for presentation proposals and attendance. GTAC will be held at the <a href="https://goo.gl/maps/ehTmRgiXqzN2">Google Sunnyvale office</a> on November 15th - 16th, 2016.<br /><br />GTAC will be streamed live on YouTube again this year, so even if you cannot attend in person, you will be able to watch the conference remotely. We will post the livestream information as we get closer to the event, and recordings will be posted afterwards.<br /><br /><b>Speakers</b><br />Presentations are targeted at students, academics, and experienced engineers working on test automation. Full presentations are 30 minutes and lightning talks are 10 minutes. Speakers should be prepared for a question and answer session following their presentation.<br /><br /><b>Application</b><br />For presentation proposals and/or attendance, <a href="https://docs.google.com/a/google.com/forms/d/1gT3jZtP03a38zaJ6gFUXb74PW6MugustSem938UWv3c/viewform">complete this form</a>. We will be selecting about 25 talks and 300 attendees for the event. The selection process is not first come first serve (no need to rush your application), and we select a diverse group of engineers from various locations, company sizes, and technical backgrounds.<br /><br /><b>Deadline</b><br />The due date for both presentation and attendance applications is <strike>June 1st, 2016</strike> June 15, 2016.<br /><br /><b>Cost</b><br />There are no registration fees, but speakers and attendees must arrange and pay for their own travel and accommodations.<br /><br /><b>More information</b><br />Please read our FAQ for most common questions<br /><a href="https://developers.google.com/google-test-automation-conference/2016/faq">https://developers.google.com/google-test-automation-conference/2016/faq</a>.]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/gtac-2016-registration-is-now-open/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>GTAC 2016 &#8211; Save the Date</title>
		<link>https://googledata.org/google-testing/gtac-2016-save-the-date/</link>
		<comments>https://googledata.org/google-testing/gtac-2016-save-the-date/#comments</comments>
		<pubDate>Fri, 08 Apr 2016 22:00:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=bc5b2779e445c26214c6190379b45985</guid>
		<description><![CDATA[<i>by Sonal Shah on behalf of the GTAC Committee</i><br /><div><br /><br /></div><div><div>We are pleased to announce that the tenth GTAC (Google Test Automation Conference) will be held on Google&#8217;s campus in <a href="https://goo.gl/maps/ehTmRgiXqzN2">Sunnyvale</a> (California, USA) on Tuesday and Wednesday, November 15th and 16th, 2016. &#160;</div><div><br /><br /></div><div>Based on feedback from the last GTAC (2015) and the increasing demand every year, we have decided to keep GTAC on a fall schedule. This schedule is a change from what we previously announced.</div><div><br /><br /></div><div>The schedule for the next few months is:</div><div><br /></div><div><b>May 1, 2016</b> &#160;- Registration opens for speakers and attendees.</div><div><strike>June 1, 2016</strike>&#160;<b>June 15, 2016</b> - Registration closes for speaker and attendee submissions.</div><div><strike>June 30, 2016</strike>&#160;<b>July 15, 2016</b> - Selected attendees will be notified.</div><div><strike>August 15, 2016</strike>&#160;<b>August 29, 2016</b> - Selected speakers will be notified.</div><div><b>November 14, 2016</b> - Rehearsal day for speakers.</div><div><b>November 15-16, 2016 </b>- GTAC 2016!</div><div><br /><br /></div><div>As part of our efforts to increase diversity of speakers and attendees at GTAC, &#160;we will be offering travel scholarships for selected applicants from traditionally underrepresented groups in technology.</div><div><br /><br /></div><div>Stay tuned to this blog and the <a href="http://g.co/gtac">GTAC website</a> for information about attending or presenting at GTAC. Please do not hesitate to contact <a href="mailto:gtac2016@google.com">gtac2016@google.com</a> if you have any questions. We look forward to seeing you there!</div></div><div><br /></div>]]></description>
				<content:encoded><![CDATA[<i>by Sonal Shah on behalf of the GTAC Committee</i><br /><div><br /><br /></div><div><div>We are pleased to announce that the tenth GTAC (Google Test Automation Conference) will be held on Google’s campus in <a href="https://goo.gl/maps/ehTmRgiXqzN2">Sunnyvale</a> (California, USA) on Tuesday and Wednesday, November 15th and 16th, 2016. &nbsp;</div><div><br /><br /></div><div>Based on feedback from the last GTAC (2015) and the increasing demand every year, we have decided to keep GTAC on a fall schedule. This schedule is a change from what we previously announced.</div><div><br /><br /></div><div>The schedule for the next few months is:</div><div><br /></div><div><b>May 1, 2016</b> &nbsp;- Registration opens for speakers and attendees.</div><div><strike>June 1, 2016</strike>&nbsp;<b>June 15, 2016</b> - Registration closes for speaker and attendee submissions.</div><div><strike>June 30, 2016</strike>&nbsp;<b>July 15, 2016</b> - Selected attendees will be notified.</div><div><strike>August 15, 2016</strike>&nbsp;<b>August 29, 2016</b> - Selected speakers will be notified.</div><div><b>November 14, 2016</b> - Rehearsal day for speakers.</div><div><b>November 15-16, 2016 </b>- GTAC 2016!</div><div><br /><br /></div><div>As part of our efforts to increase diversity of speakers and attendees at GTAC, &nbsp;we will be offering travel scholarships for selected applicants from traditionally underrepresented groups in technology.</div><div><br /><br /></div><div>Stay tuned to this blog and the <a href="http://g.co/gtac">GTAC website</a> for information about attending or presenting at GTAC. Please do not hesitate to contact <a href="mailto:gtac2016@google.com">gtac2016@google.com</a> if you have any questions. We look forward to seeing you there!</div></div><div><br /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/gtac-2016-save-the-date/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>From QA to Engineering Productivity</title>
		<link>https://googledata.org/google-testing/from-qa-to-engineering-productivity/</link>
		<comments>https://googledata.org/google-testing/from-qa-to-engineering-productivity/#comments</comments>
		<pubDate>Tue, 22 Mar 2016 20:24:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=be93ffbb85a38846163755bcae18a8c6</guid>
		<description><![CDATA[<i>By Ari Shamash   </i><br /><br />In Google&#8217;s early days, a small handful of software engineers built, tested, and released software. But as the user-base grew and products proliferated, engineers started specializing in roles, creating more scale in the development process: <br /><br /><ul><li>Test Engineers (TEs) -- &#160;tested new products and systems integration</li><li>Release Engineers (REs) -- &#160;pushed bits into production</li><li>Site Reliability Engineers (SREs) -- &#160;managed systems and data centers 24x7.</li></ul><br />This story focuses on the evolution of quality assurance and the roles of the engineers behind it at Google. &#160;The REs and SREs also evolved, but we&#8217;ll leave that for another day.<br /><br />Initially, teams relied heavily on manual operations. &#160;When we attempted to automate testing, we largely focused on the frontends, which worked, because Google was small and our products had fewer integrations. &#160;However, as Google grew, longer and longer manual test cycles bogged down iterations and delayed feature launches. &#160;Also, since we identified bugs later in the development cycle, it took us <a href="http://csse.usc.edu/TECHRPTS/1986/usccse86-501/usccse86-501.pdf">longer and longer</a> to <a href="http://dl.acm.org/citation.cfm?id=53072">fix them</a>. &#160;We determined that pushing testing upstream via <a href="https://en.wikipedia.org/wiki/Test_automation">automation</a> would help address these issues and accelerate velocity. <br /><br />As manual testing transitioned to automated processes, two separate testing roles began to emerge at Google:<br /><br /><ul><li>Test Engineers (TEs) -- With their deep product knowledge and test/quality domain expertise, TEs focused on what should be tested.</li><li>Software Engineers in Test (SETs) -- Originally software engineers with deep infrastructure and tooling expertise, SETs built the frameworks and packages required to implement automation.</li></ul><br />The impact was significant:<br /><br /><ul><li>Automated tests became more efficient and deterministic (e.g. by improving runtimes, eliminating sources of flakiness, etc.)&#160;</li><li>Metrics driven engineering proliferated (e.g. improving code and feature coverage led to higher quality products).</li></ul><br />Manual operations were reduced to manual verification on new features, and typically only in end-to-end, cross product integration boundaries. &#160;TEs developed extreme depth of knowledge for the products they supported. &#160;They became go-to engineers for product teams that needed expertise in test automation and integration. Their role evolved into a broad spectrum of responsibilities: writing scripts to automate testing, creating tools so developers could test their own code, and constantly designing better and more creative ways to identify weak spots and break software.<br /><br />SETs (in collaboration with TEs and other engineers) built a wide array of test automation tools and developed best practices that were applicable across many products. Release velocity accelerated for products. &#160;All was good, and <a href="http://www.urbandictionary.com/define.php?term=And+There+was+Much+Rejoicing">there was much rejoicing</a>! <br /><br />SETs initially focused on building tools for reducing the testing cycle time, since that was the most manually intensive and time consuming phase of getting product code into production. &#160;We made some of these tools available to the software development community: <a href="http://www.w3.org/TR/webdriver/">webdriver</a> <a href="http://www.seleniumhq.org/about/history.jsp">improvements</a>, <a href="https://angular.github.io/protractor/#/">protractor</a>, <a href="https://google.github.io/android-testing-support-library/docs/espresso/index.html">espresso</a>, <a href="http://googledevelopers.blogspot.com/2016/02/earlgrey-ios-functional-ui-testing.html">EarlGrey</a>, <a href="https://github.com/google/martian">martian proxy</a>, <a href="https://github.com/karma-runner/karma">karma</a>, and <a href="https://github.com/google/googletest">GoogleTest</a>. SETs were interested in sharing and collaborating with others in the industry and established <a href="https://developers.google.com/google-test-automation-conference">conferences</a>. The industry has also embraced the Test Engineering discipline, as other companies hired <a href="https://en.wikipedia.org/wiki/Software_Design_Engineer_in_Test">software engineers</a> into similar roles, <a href="http://www.developerdotstar.com/mag/articles/reeves_design.html">published articles</a>, and drove <a href="https://en.wikipedia.org/wiki/Test-driven_development">Test-Driven Development</a> into mainstream practices.<br /><br />Through these efforts, the testing cycle time decreased dramatically, but interestingly the overall velocity did not increase proportionately, since <a href="https://en.wikipedia.org/wiki/Queueing_theory">other phases in the development cycle became the bottleneck</a>. &#160;SETs started building tools to accelerate all other aspects of product development, including:<br /><br /><ul><li>Extending IDEs to make writing and reviewing code easier, shortening the &#8220;write code&#8221; cycle</li><li>Automating release verification, shortening the &#8220;release code&#8221; cycle.</li><li><a href="https://developers.google.com/google-test-automation-conference/2015/presentations#Day2Presentation1">Automating real time production system log verification and anomaly detection</a>, helping automate production monitoring.</li><li>Automating measurement of developer productivity, helping understand what&#8217;s working and what isn&#8217;t.</li></ul><br />In summary, the work done by the SETs naturally progressed from supporting only product testing efforts to include supporting product development efforts as well. Their role now encompassed a much broader Engineering Productivity agenda.<br /><br />Given the expanded SET charter, we wanted the title of the role to reflect the work. But what should the new title be? &#160;<a href="http://www.forbes.com/sites/laurahe/2013/03/29/googles-secrets-of-innovation-empowering-its-employees/">We empowered the SETs to choose a new title</a>, and they overwhelmingly (91%) selected Software Engineer, Tools &#38; Infrastructure (abbreviated to SETI). <br /><br />Today, SETIs and TEs still collaborate very closely on optimizing the entire development life cycle with a goal of eliminating all friction from getting features into production. Interested in building next generation tools and infrastructure? &#160;Join us (<a href="http://g.co/engprod/seti">SETI</a>, <a href="http://g.co/engprod/te">TE</a>)!<br /><br />]]></description>
				<content:encoded><![CDATA[<i>By Ari Shamash   </i><br /><br />In Google’s early days, a small handful of software engineers built, tested, and released software. But as the user-base grew and products proliferated, engineers started specializing in roles, creating more scale in the development process: <br /><br /><ul><li>Test Engineers (TEs) -- &nbsp;tested new products and systems integration</li><li>Release Engineers (REs) -- &nbsp;pushed bits into production</li><li>Site Reliability Engineers (SREs) -- &nbsp;managed systems and data centers 24x7.</li></ul><br />This story focuses on the evolution of quality assurance and the roles of the engineers behind it at Google. &nbsp;The REs and SREs also evolved, but we’ll leave that for another day.<br /><br />Initially, teams relied heavily on manual operations. &nbsp;When we attempted to automate testing, we largely focused on the frontends, which worked, because Google was small and our products had fewer integrations. &nbsp;However, as Google grew, longer and longer manual test cycles bogged down iterations and delayed feature launches. &nbsp;Also, since we identified bugs later in the development cycle, it took us <a href="http://csse.usc.edu/TECHRPTS/1986/usccse86-501/usccse86-501.pdf">longer and longer</a> to <a href="http://dl.acm.org/citation.cfm?id=53072">fix them</a>. &nbsp;We determined that pushing testing upstream via <a href="https://en.wikipedia.org/wiki/Test_automation">automation</a> would help address these issues and accelerate velocity. <br /><br />As manual testing transitioned to automated processes, two separate testing roles began to emerge at Google:<br /><br /><ul><li>Test Engineers (TEs) -- With their deep product knowledge and test/quality domain expertise, TEs focused on what should be tested.</li><li>Software Engineers in Test (SETs) -- Originally software engineers with deep infrastructure and tooling expertise, SETs built the frameworks and packages required to implement automation.</li></ul><br />The impact was significant:<br /><br /><ul><li>Automated tests became more efficient and deterministic (e.g. by improving runtimes, eliminating sources of flakiness, etc.)&nbsp;</li><li>Metrics driven engineering proliferated (e.g. improving code and feature coverage led to higher quality products).</li></ul><br />Manual operations were reduced to manual verification on new features, and typically only in end-to-end, cross product integration boundaries. &nbsp;TEs developed extreme depth of knowledge for the products they supported. &nbsp;They became go-to engineers for product teams that needed expertise in test automation and integration. Their role evolved into a broad spectrum of responsibilities: writing scripts to automate testing, creating tools so developers could test their own code, and constantly designing better and more creative ways to identify weak spots and break software.<br /><br />SETs (in collaboration with TEs and other engineers) built a wide array of test automation tools and developed best practices that were applicable across many products. Release velocity accelerated for products. &nbsp;All was good, and <a href="http://www.urbandictionary.com/define.php?term=And+There+was+Much+Rejoicing">there was much rejoicing</a>! <br /><br />SETs initially focused on building tools for reducing the testing cycle time, since that was the most manually intensive and time consuming phase of getting product code into production. &nbsp;We made some of these tools available to the software development community: <a href="http://www.w3.org/TR/webdriver/">webdriver</a> <a href="http://www.seleniumhq.org/about/history.jsp">improvements</a>, <a href="https://angular.github.io/protractor/#/">protractor</a>, <a href="https://google.github.io/android-testing-support-library/docs/espresso/index.html">espresso</a>, <a href="http://googledevelopers.blogspot.com/2016/02/earlgrey-ios-functional-ui-testing.html">EarlGrey</a>, <a href="https://github.com/google/martian">martian proxy</a>, <a href="https://github.com/karma-runner/karma">karma</a>, and <a href="https://github.com/google/googletest">GoogleTest</a>. SETs were interested in sharing and collaborating with others in the industry and established <a href="https://developers.google.com/google-test-automation-conference">conferences</a>. The industry has also embraced the Test Engineering discipline, as other companies hired <a href="https://en.wikipedia.org/wiki/Software_Design_Engineer_in_Test">software engineers</a> into similar roles, <a href="http://www.developerdotstar.com/mag/articles/reeves_design.html">published articles</a>, and drove <a href="https://en.wikipedia.org/wiki/Test-driven_development">Test-Driven Development</a> into mainstream practices.<br /><br />Through these efforts, the testing cycle time decreased dramatically, but interestingly the overall velocity did not increase proportionately, since <a href="https://en.wikipedia.org/wiki/Queueing_theory">other phases in the development cycle became the bottleneck</a>. &nbsp;SETs started building tools to accelerate all other aspects of product development, including:<br /><br /><ul><li>Extending IDEs to make writing and reviewing code easier, shortening the “write code” cycle</li><li>Automating release verification, shortening the “release code” cycle.</li><li><a href="https://developers.google.com/google-test-automation-conference/2015/presentations#Day2Presentation1">Automating real time production system log verification and anomaly detection</a>, helping automate production monitoring.</li><li>Automating measurement of developer productivity, helping understand what’s working and what isn’t.</li></ul><br />In summary, the work done by the SETs naturally progressed from supporting only product testing efforts to include supporting product development efforts as well. Their role now encompassed a much broader Engineering Productivity agenda.<br /><br />Given the expanded SET charter, we wanted the title of the role to reflect the work. But what should the new title be? &nbsp;<a href="http://www.forbes.com/sites/laurahe/2013/03/29/googles-secrets-of-innovation-empowering-its-employees/">We empowered the SETs to choose a new title</a>, and they overwhelmingly (91%) selected Software Engineer, Tools &amp; Infrastructure (abbreviated to SETI). <br /><br />Today, SETIs and TEs still collaborate very closely on optimizing the entire development life cycle with a goal of eliminating all friction from getting features into production. Interested in building next generation tools and infrastructure? &nbsp;Join us (<a href="http://g.co/engprod/seti">SETI</a>, <a href="http://g.co/engprod/te">TE</a>)!<br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/from-qa-to-engineering-productivity/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>EarlGrey &#8211; iOS Functional UI Testing Framework</title>
		<link>https://googledata.org/google-testing/earlgrey-ios-functional-ui-testing-framework/</link>
		<comments>https://googledata.org/google-testing/earlgrey-ios-functional-ui-testing-framework/#comments</comments>
		<pubDate>Tue, 16 Feb 2016 23:14:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=c6ccb82c906ad4abdee4363029837004</guid>
		<description><![CDATA[By Siddartha Janga on behalf of Google iOS Developers&#160;Brewing for quite some time, we are excited to announce EarlGrey, a functional UI testing framework for iOS. Several Google apps like YouTube, Google Calendar, Google Photos, Google Translate, ...]]></description>
				<content:encoded><![CDATA[<i>By Siddartha Janga on behalf of Google iOS Developers&nbsp;</i><br /><br />Brewing for quite some time, we are excited to announce EarlGrey, a functional UI testing framework for iOS. Several Google apps like <a href="https://itunes.apple.com/us/app/youtube/id544007664?mt=8">YouTube</a>, <a href="https://itunes.apple.com/us/app/google-calendar/id909319292?mt=8">Google Calendar</a>, <a href="https://itunes.apple.com/us/app/google-photos-store-search/id962194608?mt=8">Google Photos</a>, <a href="https://itunes.apple.com/us/app/google-translate/id414706506?mt=8">Google Translate</a>, <a href="https://itunes.apple.com/us/app/google-play-music/id691797987?mt=8">Google Play Music</a> and many more have successfully adopted the framework for their functional testing needs.<br /><br />The key features offered by EarlGrey include:<br /><br /><ul><li><b>Powerful built-in synchronization :</b> Tests will automatically wait for events such as animations, network requests, etc. before interacting with the UI. This will result in tests that are easier to write (no sleeps or waits) and simple to maintain (straight up procedural description of test steps).&nbsp;</li><li><b>Visibility checking :</b> All interactions occur on elements that users can see. For example, attempting to tap a button that is behind an image will lead to test failure immediately.&nbsp;</li><li><b>Flexible design : </b>The components that determine element selection, interaction, assertion and synchronization have been designed to be extensible.&nbsp;</li></ul><br /><br />Are you in need for a cup of refreshing EarlGrey? EarlGrey has been open sourced under the <a href="https://github.com/google/EarlGrey/blob/master/LICENSE">Apache license</a>. Check out the <a href="https://github.com/google/EarlGrey">getting started guide</a> and add EarlGrey to your project using <a href="https://cocoapods.org/">CocoaPods</a> or manually add it to your Xcode project file. <br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/earlgrey-ios-functional-ui-testing-framework/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>GTAC 2015 Wrap Up</title>
		<link>https://googledata.org/google-testing/gtac-2015-wrap-up/</link>
		<comments>https://googledata.org/google-testing/gtac-2015-wrap-up/#comments</comments>
		<pubDate>Tue, 08 Dec 2015 20:40:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=434768a51f18d8429f2678b65c372ed6</guid>
		<description><![CDATA[<i>by Michael Klepikov and Lesley Katzen on behalf of the GTAC Committee</i><br /><br />The ninth <a href="http://g.co/gtac">GTAC</a> (Google Test Automation Conference) was held on November 10-11 at the <a href="http://www.google.com/about/careers/locations/cambridge/">Google Cambridge</a> office, the &#8220;Hub&#8221; of innovation. The conference was completely packed with presenters and attendees from all over the world, from industry and academia, discussing advances in test automation and the test engineering computer science field, bringing with them a huge diversity of experiences. Speakers from numerous companies and universities (Applitools, Automattic, Bitbar, Georgia Tech, Google, Indian Institute of Science, Intel, LinkedIn, Lockheed Martin, MIT, Nest, Netflix, OptoFidelity, Splunk, Supersonic, Twitter, Uber, University of Waterloo) spoke on a variety of interesting and cutting edge test automation topics. <br /><br /><div><a href="http://3.bp.blogspot.com/-y8eJDyTpZLc/Vmc-EgabRBI/AAAAAAAAAM4/Xc1sMt4SWkg/s1600/GTAC2015-4520.jpg"><img border="0" height="266" src="http://3.bp.blogspot.com/-y8eJDyTpZLc/Vmc-EgabRBI/AAAAAAAAAM4/Xc1sMt4SWkg/s400/GTAC2015-4520.jpg" width="400"></a></div><div><a href="http://1.bp.blogspot.com/-PWoPLlUq3NY/Vmc-oIl6uyI/AAAAAAAAANA/cVsvQOVI_8g/s1600/GTAC2015-4964.jpg"><img border="0" height="266" src="http://1.bp.blogspot.com/-PWoPLlUq3NY/Vmc-oIl6uyI/AAAAAAAAANA/cVsvQOVI_8g/s400/GTAC2015-4964.jpg" width="400"></a></div><br />All presentation videos and slides are posted on the <a href="https://developers.google.com/google-test-automation-conference/2015/stream">Video Recordings</a> and <a href="https://developers.google.com/google-test-automation-conference/2015/presentations">Presentations</a> pages. All videos have professionally transcribed closed captions, and the YouTube descriptions have the slides links. Enjoy and share! <br /><br />We had over 1,300 applicants and over 200 of those for speaking. Over 250 people filled our venue to capacity, and the live stream had a peak of about 400 concurrent viewers, with about 3,300 total viewing hours. <br /><br />Our goal in hosting GTAC is to make the conference highly relevant and useful for both attendees and the larger test engineering community as a whole. Our post-conference survey shows that we are close to achieving that goal; thanks to everyone who completed the feedback survey!<br /><br /><ul><li>Our 82 survey respondents were mostly (81%) test focused professionals with a wide range of 1 to 40 years of experience.&#160;</li><li>Another 76% of respondents rated the conference as a whole as above average, with marked satisfaction for the venue, the food (those Diwali treats!), and the breadth and coverage of the talks themselves.</li></ul><br /><div><a href="http://4.bp.blogspot.com/-NaEwJbMvasg/Vmc_AwG4ZQI/AAAAAAAAANI/LC5l1LyB8oE/s1600/GTAC2015-4819.jpg"><img border="0" height="266" src="http://4.bp.blogspot.com/-NaEwJbMvasg/Vmc_AwG4ZQI/AAAAAAAAANI/LC5l1LyB8oE/s400/GTAC2015-4819.jpg" width="400"></a></div><br />The top five most popular talks were:<br /><br /><ul><li>The Uber Challenge of Cross-Application/Cross-Device Testing (Apple Chow and Bian Jiang)&#160;</li><li>Your Tests Aren't Flaky (Alister Scott)&#160;</li><li>Statistical Data Sampling (Celal Ziftci and Ben Greenberg)&#160;</li><li>Coverage is Not Strongly Correlated with Test Suite Effectiveness (Laura Inozemtseva)&#160;</li><li>Chrome OS Test Automation Lab (Simran Basi and Chris Sosa).</li></ul><br /><div><a href="http://1.bp.blogspot.com/-WxbA1FGTRo0/Vmc_REC1-iI/AAAAAAAAANQ/_lMTcGDkN4g/s1600/GTAC2015-4657.jpg"><img border="0" height="400" src="http://1.bp.blogspot.com/-WxbA1FGTRo0/Vmc_REC1-iI/AAAAAAAAANQ/_lMTcGDkN4g/s400/GTAC2015-4657.jpg" width="266"></a></div><br />Our social events also proved  to be crowd pleasers.  The social events were a direct response to feedback from GTAC 2014 for organized opportunities for socialization among the GTAC attendees. <br /><br /><div><a href="http://2.bp.blogspot.com/-cd2hd3VYKyw/Vmc_jrqt4zI/AAAAAAAAANY/KGsJPyBaL8A/s1600/GTAC2015-4871.jpg"><img border="0" height="266" src="http://2.bp.blogspot.com/-cd2hd3VYKyw/Vmc_jrqt4zI/AAAAAAAAANY/KGsJPyBaL8A/s400/GTAC2015-4871.jpg" width="400"></a></div><br />This isn&#8217;t to say there isn&#8217;t room for improvement. We had 11% of respondents express frustration with event communications and provided some long, thoughtful suggestions for what we could do to improve next year. Also, many of the long form comments asked for a better mix of technologies, noting that mobile had a big presence in the talks this year.  <br /><br />If you have any suggestions on how we can improve, please comment on this post, or better yet &#8211; fill out the <a href="https://docs.google.com/a/google.com/forms/d/1_1Jb23jsTxoVat-HGoKJyJ9BcfdvoDWIpatLqv6fTNA/viewform">survey</a>, which remains open.  Based on feedback from last year urging more transparency in speaker selection, we included an individual outside of Google in the speaker evaluation.  Feedback is precious, we take it very seriously, and we will use it to improve next time around. <br /><br />Thank you to all the speakers, attendees, and online viewers who made this a special event once again. To receive announcements about the next GTAC, currently planned for early 2017, subscribe to the <a href="http://googletesting.blogspot.com/">Google Testing Blog</a>. <br /><br />]]></description>
				<content:encoded><![CDATA[<i>by Michael Klepikov and Lesley Katzen on behalf of the GTAC Committee</i><br /><br />The ninth <a href="http://g.co/gtac">GTAC</a> (Google Test Automation Conference) was held on November 10-11 at the <a href="http://www.google.com/about/careers/locations/cambridge/">Google Cambridge</a> office, the “Hub” of innovation. The conference was completely packed with presenters and attendees from all over the world, from industry and academia, discussing advances in test automation and the test engineering computer science field, bringing with them a huge diversity of experiences. Speakers from numerous companies and universities (Applitools, Automattic, Bitbar, Georgia Tech, Google, Indian Institute of Science, Intel, LinkedIn, Lockheed Martin, MIT, Nest, Netflix, OptoFidelity, Splunk, Supersonic, Twitter, Uber, University of Waterloo) spoke on a variety of interesting and cutting edge test automation topics. <br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-y8eJDyTpZLc/Vmc-EgabRBI/AAAAAAAAAM4/Xc1sMt4SWkg/s1600/GTAC2015-4520.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="266" src="http://3.bp.blogspot.com/-y8eJDyTpZLc/Vmc-EgabRBI/AAAAAAAAAM4/Xc1sMt4SWkg/s400/GTAC2015-4520.jpg" width="400" /></a></div><div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-PWoPLlUq3NY/Vmc-oIl6uyI/AAAAAAAAANA/cVsvQOVI_8g/s1600/GTAC2015-4964.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="266" src="http://1.bp.blogspot.com/-PWoPLlUq3NY/Vmc-oIl6uyI/AAAAAAAAANA/cVsvQOVI_8g/s400/GTAC2015-4964.jpg" width="400" /></a></div><br />All presentation videos and slides are posted on the <a href="https://developers.google.com/google-test-automation-conference/2015/stream">Video Recordings</a> and <a href="https://developers.google.com/google-test-automation-conference/2015/presentations">Presentations</a> pages. All videos have professionally transcribed closed captions, and the YouTube descriptions have the slides links. Enjoy and share! <br /><br />We had over 1,300 applicants and over 200 of those for speaking. Over 250 people filled our venue to capacity, and the live stream had a peak of about 400 concurrent viewers, with about 3,300 total viewing hours. <br /><br />Our goal in hosting GTAC is to make the conference highly relevant and useful for both attendees and the larger test engineering community as a whole. Our post-conference survey shows that we are close to achieving that goal; thanks to everyone who completed the feedback survey!<br /><br /><ul><li>Our 82 survey respondents were mostly (81%) test focused professionals with a wide range of 1 to 40 years of experience.&nbsp;</li><li>Another 76% of respondents rated the conference as a whole as above average, with marked satisfaction for the venue, the food (those Diwali treats!), and the breadth and coverage of the talks themselves.</li></ul><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-NaEwJbMvasg/Vmc_AwG4ZQI/AAAAAAAAANI/LC5l1LyB8oE/s1600/GTAC2015-4819.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="266" src="http://4.bp.blogspot.com/-NaEwJbMvasg/Vmc_AwG4ZQI/AAAAAAAAANI/LC5l1LyB8oE/s400/GTAC2015-4819.jpg" width="400" /></a></div><br />The top five most popular talks were:<br /><br /><ul><li>The Uber Challenge of Cross-Application/Cross-Device Testing (Apple Chow and Bian Jiang)&nbsp;</li><li>Your Tests Aren't Flaky (Alister Scott)&nbsp;</li><li>Statistical Data Sampling (Celal Ziftci and Ben Greenberg)&nbsp;</li><li>Coverage is Not Strongly Correlated with Test Suite Effectiveness (Laura Inozemtseva)&nbsp;</li><li>Chrome OS Test Automation Lab (Simran Basi and Chris Sosa).</li></ul><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-WxbA1FGTRo0/Vmc_REC1-iI/AAAAAAAAANQ/_lMTcGDkN4g/s1600/GTAC2015-4657.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="http://1.bp.blogspot.com/-WxbA1FGTRo0/Vmc_REC1-iI/AAAAAAAAANQ/_lMTcGDkN4g/s400/GTAC2015-4657.jpg" width="266" /></a></div><br />Our social events also proved  to be crowd pleasers.  The social events were a direct response to feedback from GTAC 2014 for organized opportunities for socialization among the GTAC attendees. <br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-cd2hd3VYKyw/Vmc_jrqt4zI/AAAAAAAAANY/KGsJPyBaL8A/s1600/GTAC2015-4871.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="266" src="http://2.bp.blogspot.com/-cd2hd3VYKyw/Vmc_jrqt4zI/AAAAAAAAANY/KGsJPyBaL8A/s400/GTAC2015-4871.jpg" width="400" /></a></div><br />This isn’t to say there isn’t room for improvement. We had 11% of respondents express frustration with event communications and provided some long, thoughtful suggestions for what we could do to improve next year. Also, many of the long form comments asked for a better mix of technologies, noting that mobile had a big presence in the talks this year.  <br /><br />If you have any suggestions on how we can improve, please comment on this post, or better yet – fill out the <a href="https://docs.google.com/a/google.com/forms/d/1_1Jb23jsTxoVat-HGoKJyJ9BcfdvoDWIpatLqv6fTNA/viewform">survey</a>, which remains open.  Based on feedback from last year urging more transparency in speaker selection, we included an individual outside of Google in the speaker evaluation.  Feedback is precious, we take it very seriously, and we will use it to improve next time around. <br /><br />Thank you to all the speakers, attendees, and online viewers who made this a special event once again. To receive announcements about the next GTAC, currently planned for early 2017, subscribe to the <a href="http://googletesting.blogspot.com/">Google Testing Blog</a>. <br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/gtac-2015-wrap-up/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>GTAC 2015 is Next Week!</title>
		<link>https://googledata.org/google-testing/gtac-2015-is-next-week/</link>
		<comments>https://googledata.org/google-testing/gtac-2015-is-next-week/#comments</comments>
		<pubDate>Sat, 07 Nov 2015 02:46:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=dd2a53fb5ab2a7891f93d7f1045108ca</guid>
		<description><![CDATA[by Anthony Vallone on behalf of the GTAC CommitteeThe ninth GTAC (Google Test Automation Conference) commences on Tuesday, November 10th, at the Google Cambridge office. You can find the latest details on the conference site, including schedule, speake...]]></description>
				<content:encoded><![CDATA[<i>by <a href="http://anthonyvallone.com/">Anthony Vallone</a> on behalf of the GTAC Committee</i><br /><br />The ninth GTAC (Google Test Automation Conference) commences on Tuesday, November 10th, at the Google Cambridge office. You can find the latest details on the <a href="https://developers.google.com/google-test-automation-conference/">conference site</a>, including <a href="https://developers.google.com/google-test-automation-conference/2015/schedule">schedule</a>, <a href="https://developers.google.com/google-test-automation-conference/2015/speakers">speaker profiles</a>, and <a href="https://developers.google.com/google-test-automation-conference/2015/travel">travel tips</a>.<br /><br />If you have not been invited to attend in person, you can <a href="https://developers.google.com/google-test-automation-conference/2015/stream">watch the event live</a>. And if you miss the livestream, we will post slides and videos later.<br /><br />We have an outstanding speaker lineup this year, and we look forward to seeing you all there or online! <br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/gtac-2015-is-next-week/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Announcing the GTAC 2015 Agenda</title>
		<link>https://googledata.org/google-testing/announcing-the-gtac-2015-agenda/</link>
		<comments>https://googledata.org/google-testing/announcing-the-gtac-2015-agenda/#comments</comments>
		<pubDate>Tue, 27 Oct 2015 23:52:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=08d887d3edd547ba4e11c046581d4d52</guid>
		<description><![CDATA[by Anthony Vallone on behalf of the GTAC Committee&#160;We have completed the selection and confirmation of all speakers and attendees for GTAC 2015. You can find the detailed agenda at: developers.google.com/gtac/2015/schedule.Thank you to all who sub...]]></description>
				<content:encoded><![CDATA[<i>by <a href="http://anthonyvallone.com/">Anthony Vallone</a> on behalf of the GTAC Committee&nbsp;</i><br /><br />We have completed the selection and confirmation of all speakers and attendees for GTAC 2015. You can find the detailed agenda at: <a href="http://developers.google.com/gtac/2015/schedule">developers.google.com/gtac/2015/schedule</a>.<br /><br />Thank you to all who submitted proposals!<br /><br />There is a lot of interest in GTAC once again this year with about 1400 applicants and about 200 of those for speaking. Unfortunately, our venue only seats 250. We will livestream the event as usual, so fret not if you were not selected to attend. Information about the livestream and other details will be posted on the GTAC site soon and announced here. <br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/announcing-the-gtac-2015-agenda/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Audio Testing &#8211; Automatic Gain Control</title>
		<link>https://googledata.org/google-testing/audio-testing-automatic-gain-control/</link>
		<comments>https://googledata.org/google-testing/audio-testing-automatic-gain-control/#comments</comments>
		<pubDate>Thu, 08 Oct 2015 16:21:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=cee7a08ad95ade94f70dfcc1ea246349</guid>
		<description><![CDATA[<i>By: Patrik H&#246;glund </i><br /><br /><h2>What is Automatic Gain Control?&#160;</h2>It&#8217;s time to talk about advanced media quality tests again! As experienced Google testing blog readers know, when I write an article it&#8217;s usually about WebRTC, and the unusual testing solutions we build to test it. This article is no exception. Today we&#8217;re going to talk about Automatic Gain Control, or AGC. This is a feature that&#8217;s on by default for WebRTC applications, such as <a href="http://apprtc.appspot.com/">http://apprtc.appspot.com</a>. It uses various means to adjust the microphone signal so your voice makes it loud and clear to the other side of the peer connection. For instance, it can attempt to adjust your microphone gain or try to amplify the signal digitally.<br /><br /><div><a href="http://3.bp.blogspot.com/-gTvHr_vpehs/VhaQZ78-y5I/AAAAAAAAAL0/Z4BAXUNDNcU/s1600/image03.png"><img border="0" height="336" src="http://3.bp.blogspot.com/-gTvHr_vpehs/VhaQZ78-y5I/AAAAAAAAAL0/Z4BAXUNDNcU/s640/image03.png" width="640"></a></div><div><i>Figure 1. How Auto Gain Control works [<a href="https://code.google.com/p/chromium/codesearch#chromium/src/third_party/webrtc/modules/audio_processing/agc/agc_manager_direct.h&#38;sq=package:chromium">code here</a>]. </i></div><div><br /></div>This is an example of automatic control engineering (another example would be the classic <a href="https://en.wikipedia.org/wiki/PID_controller">PID controller</a>) and happens in real time. Therefore, if you move closer to the mic while speaking, the AGC will notice the output stream is too loud, and reduce mic volume and/or digital gain. When you move further away, it tries to adapt up again. The fancy voice activity detector is there so we only amplify speech, and not, say, the microwave oven your spouse just started in the other room.<br /><h2>Testing the AGC</h2>Now, how do we make sure the AGC works? The first thing is obviously to <a href="https://code.google.com/p/chromium/codesearch#chromium/src/third_party/webrtc/modules/audio_processing/agc/agc_unittest.cc&#38;sq=package:chromium">write unit tests</a> and <a href="https://code.google.com/p/chromium/codesearch#chromium/src/third_party/webrtc/modules/audio_processing/test/">integration tests</a>. You <a href="http://googletesting.blogspot.com/2015/04/just-say-no-to-more-end-to-end-tests.html">didn&#8217;t think about building that end-to-end test first, did you</a>? Once we have the lower-level tests in place, we can start looking at a bigger test. While developing the WebRTC implementation in Chrome, we had several bugs where the AGC code was working by itself, but was misconfigured in Chrome. In one case, it was simply turned off for all users. In another, it was only turned off in Hangouts.  <br /><br />Only an end-to-end test can catch these integration issues, and we already had <a href="http://googletesting.blogspot.com/2013/11/webrtc-audio-quality-testing.html">stable, low-maintenance audio quality tests</a> with the ability to record Chrome&#8217;s output sound for analysis. I encourage you to read that article, but the bottom line is that those tests can run a WebRTC call in two tabs and record the audio output to a file. Those tests run the <a href="https://en.wikipedia.org/wiki/PESQ">PESQ</a> algorithm on input and output to see how similar they are. <br /><br />That&#8217;s a good framework to have, but I needed to make two changes:<br /><br /><ul><li>Add file support to Chrome&#8217;s fake audio input device, so we can play a known file. The original audio test avoided this by using WebAudio, but AGC doesn&#8217;t run in the WebAudio path, just the microphone capture path, so that won&#8217;t work.</li><li>Instead of running PESQ, run an analysis that compares the gain between input and output.</li></ul><h2>Adding Fake File Support</h2>This is always a big part of the work in media testing: controlling the input and output. It&#8217;s unworkable to tape microphones to loudspeakers or point cameras to screens to capture the media, so the easiest solution is usually to add a debug flag. It is exactly what I did <a href="https://code.google.com/p/chromium/codesearch#chromium/src/media/audio/fake_audio_input_stream.cc&#38;sq=package:chromium&#38;type=cs&#38;rcl=1443324274&#38;l=118">here</a>. It was a lot of work, but I won&#8217;t go into much detail since Chrome&#8217;s audio pipeline is complex. The core is <a href="https://code.google.com/p/chromium/codesearch#chromium/src/media/audio/simple_sources.cc&#38;sq=package:chromium&#38;type=cs">this</a>: <br /><br /><pre><span>int</span> FileSource::OnMoreData(AudioBus* audio_bus, uint32 total_bytes_delay) {<br /><span>// Load the file if we haven't already. This load needs to happen on the</span><br /><span>// audio thread, otherwise we'll run on the UI thread on Mac for instance.</span><br /><span>// This will massively delay the first OnMoreData, but we'll catch up.</span><br /><span>if</span> (!wav_audio_handler_)<br />    LoadWavFile(path_to_wav_file_);<br /><span>if</span> (load_failed_)<br /><span>return</span> 0;<br /><br />  DCHECK(wav_audio_handler_.get());<br /><br /><span>// Stop playing if we've played out the whole file.</span><br /><span>if</span> (wav_audio_handler_-&#62;AtEnd(wav_file_read_pos_))<br /><span>return</span> 0;<br /><br /><span>// This pulls data from ProvideInput.</span><br />  file_audio_converter_-&#62;Convert(audio_bus);<br /><span>return</span> audio_bus-&#62;frames();<br />}<br /></pre><br />This code runs every 10 ms and reads a small chunk from the file, converts it to Chrome&#8217;s preferred audio format and sends it on through the audio pipeline. After implementing this, I could simply run: <br /><br /><pre>chrome --use-fake-device-for-media-stream <br />       --use-file-for-fake-audio-capture=/tmp/file.wav<br /></pre><br />and whenever I hit a webpage that used WebRTC, the above file would play instead of my microphone input. Sweet!<br /><h2>The Analysis Stage</h2>Next I had to get the analysis stage figured out. It turned out there was something called an <a href="https://code.google.com/p/chromium/codesearch#chromium/src/media/audio/audio_power_monitor.h&#38;q=audiopowermo&#38;sq=package:chromium&#38;l=36">AudioPowerMonitor</a> in the Chrome code, which you feed audio data into and get the average audio power for the data you fed in. This is a measure of how &#8220;loud&#8221; the audio is. Since the whole point of the AGC is getting to the right audio power level, we&#8217;re looking to compute<br /><br /><i>A<sub>diff</sub> = A<sub>out</sub> - A<sub>in</sub></i><br /><br />Or, really, how much louder or weaker is the output compared to the input audio? Then we can construct different scenarios: <i>A<sub>diff</sub></i> should be 0 if the AGC is turned off and it should be &#62; 0 dB if the AGC is on and we feed in a low power audio file. Computing the average energy of an audio file was straightforward to <a href="https://code.google.com/p/chromium/codesearch#chromium/src/chrome/browser/media/webrtc_browsertest_audio.cc&#38;sq=package:chromium&#38;type=cs&#38;l=56">implement</a>: <br /><br /><pre>  <span>// ...</span><br />  size_t bytes_written;<br />  wav_audio_handler-&#62;CopyTo(audio_bus.get(), 0, &#38;bytes_written);<br />  CHECK_EQ(bytes_written, wav_audio_handler-&#62;data().size())<br />      &#60;&#60; <span>"Expected to write entire file into bus."</span>;<br /><br /><span>// Set the filter coefficient to the whole file's duration; this will make</span><br /><span>// the power monitor take the entire file into account.</span><br />  media::AudioPowerMonitor power_monitor(wav_audio_handler-&#62;sample_rate(),<br />                                         file_duration);<br />  power_monitor.Scan(*audio_bus, audio_bus-&#62;frames());<br /><span>// ...</span><br /><span>return</span> power_monitor.ReadCurrentPowerAndClip().first;</pre><br />I wrote a new test, and hooked up the above logic instead of PESQ. I could compute&#160;<i>A<sub>in</sub></i>&#160;by running the above algorithm on the reference file (which I fed in using the flag I implemented above) and <i>A<sub>out</sub></i> on the recording of the output audio. At this point I pretty much thought I was done. I ran a WebRTC call with the AGC turned off, expecting to get zero&#8230; and got a huge number. Turns out I wasn&#8217;t done.<br /><h2>What Went Wrong?</h2>I needed more debugging information to figure out what went wrong. Since the AGC was off, I would expect the power curves for output and input to be identical. All I had was the average audio power over the entire file, so I started plotting the audio power for each 10 millisecond segment instead to understand where the curves diverged. I could then plot the detected audio power over the time of the test. I started by plotting <i>A<sub>diff&#160;</sub></i>: <br /><br /><div><a href="http://1.bp.blogspot.com/-DjKeQ5-Bh24/VhaQdgGzpaI/AAAAAAAAAMI/Rpr3raMc0F4/s1600/image01.png"><img border="0" height="161" src="http://1.bp.blogspot.com/-DjKeQ5-Bh24/VhaQdgGzpaI/AAAAAAAAAMI/Rpr3raMc0F4/s640/image01.png" width="640"></a></div><div><i>Figure 2. Plot of A<sub>diff</sub>.</i></div><br />The difference is quite small in the beginning, but grows in amplitude over time. Interesting. I then plotted <i>A<sub>out</sub></i> and <i>A<sub>in</sub></i> next to each other:  <br /><br /><div><a href="http://4.bp.blogspot.com/-32eITCuxF1c/VhaQbhizILI/AAAAAAAAAMA/FuRSRd2-2ek/s1600/image00.png"><img border="0" height="249" src="http://4.bp.blogspot.com/-32eITCuxF1c/VhaQbhizILI/AAAAAAAAAMA/FuRSRd2-2ek/s640/image00.png" width="640"></a></div><div><i>Figure 3. Plot of&#160;A<sub>out&#160;</sub>and&#160;A<sub>in</sub>.</i></div><br />A-ha! The curves drift apart over time; the above shows about 10 seconds of time, and the drift is maybe 80 ms at the end. The more they drift apart, the bigger the diff becomes. Exasperated, I asked our audio engineers about the above. Had my fancy test found its first bug? No, as it turns out - it was by design.<br /><h2>Clock Drift and Packet Loss</h2>Let me explain. As a part of WebRTC audio processing, we run a complex module called <a href="https://code.google.com/p/chromium/codesearch#chromium/src/third_party/webrtc/modules/audio_coding/neteq/&#38;q=neteq&#38;sq=package:chromium">NetEq</a> on the received audio stream. When sending audio over the Internet, there will inevitably be <i>packet loss</i> and <i>clock drift</i>. Packet losses always happen on the Internet, depending on the network path between sender and receiver. Clock drift happens because the sample clocks on the sending and receiving sound cards are not perfectly synced. <br /><br />In this particular case, the problem was not packet loss since we have ideal network conditions (one machine, packets go over the machine&#8217;s loopback interface = zero packet loss). But how can we have clock drift? Well, recall the fake device I wrote earlier that reads a file? It never touches the sound card like when the sound comes from the mic, so it runs on the system clock. That clock will drift against the machine&#8217;s sound card clock, even when we are on the same machine.  <br /><br />NetEq uses clever algorithms to conceal clock drift and packet loss. Most commonly it applies time compression or stretching on the audio it plays out, which means it makes the audio a little shorter or longer when needed to compensate for the drift. We humans mostly don&#8217;t even notice that, whereas a drift left uncompensated would result in a depleted or flooded receiver buffer &#8211; very noticeable. Anyway, I digress. This drift of the recording vs. the reference file was natural and I would just have to deal with it.<br /><h2>Silence Splitting to the Rescue!</h2>I could probably have solved this with math and postprocessing of the results (<a href="https://en.wikipedia.org/wiki/Least_squares">least squares</a>  maybe?), but I had another idea. The reference file happened to be comprised of five segments with small pauses between them. What if I made these pauses longer, split the files on the pauses and trimmed away all the silence? This would effectively align the start of each segment with its corresponding segment in the reference file.  <br /><br /><div><a href="http://2.bp.blogspot.com/-dsxRyso4oLE/VhaQiGyCxUI/AAAAAAAAAMg/TLldcn7OYek/s1600/image05.png"><img border="0" height="112" src="http://2.bp.blogspot.com/-dsxRyso4oLE/VhaQiGyCxUI/AAAAAAAAAMg/TLldcn7OYek/s640/image05.png" width="640"></a></div><div><i>Figure 4. Before silence splitting.</i></div><br /><div><a href="http://1.bp.blogspot.com/-Z0MlHuMC4pI/VhaQg2cK-FI/AAAAAAAAAMY/m7jCmlRmnJU/s1600/image04.png"><img border="0" height="176" src="http://1.bp.blogspot.com/-Z0MlHuMC4pI/VhaQg2cK-FI/AAAAAAAAAMY/m7jCmlRmnJU/s640/image04.png" width="640"></a></div><div><i>Figure 5. After silence splitting.</i></div><br />We would still have NetEQ drift, but as you can see its effects will not stack up towards the end, so if the segments are short enough we should be able to mitigate this problem.<br /><h2>Result</h2>Here is the <a href="https://code.google.com/p/chromium/codesearch#chromium/src/chrome/browser/media/chrome_webrtc_audio_quality_browsertest.cc">final test implementation</a>:  <br /><br /><pre>  base::FilePath reference_file = <br />      test::GetReferenceFilesDir().Append(reference_filename);<br />  base::FilePath recording = CreateTemporaryWaveFile();<br /><br />  ASSERT_NO_FATAL_FAILURE(SetupAndRecordAudioCall(<br />      reference_file, recording, constraints,<br />      base::TimeDelta::FromSeconds(30)));<br /><br />  base::ScopedTempDir split_ref_files;<br />  ASSERT_TRUE(split_ref_files.CreateUniqueTempDir());<br />  ASSERT_NO_FATAL_FAILURE(<br />      SplitFileOnSilenceIntoDir(reference_file, split_ref_files.path()));<br />  std::<span>vector</span>&#60;base::FilePath&#62; ref_segments =<br />      ListWavFilesInDir(split_ref_files.path());<br /><br />  base::ScopedTempDir split_actual_files;<br />  ASSERT_TRUE(split_actual_files.CreateUniqueTempDir());<br />  ASSERT_NO_FATAL_FAILURE(<br />      SplitFileOnSilenceIntoDir(recording, split_actual_files.path()));<br /><br /><span>// Keep the recording and split files if the analysis fails.</span><br />  base::FilePath actual_files_dir = split_actual_files.Take();<br />  std::<span>vector</span>&#60;base::FilePath&#62; actual_segments =<br />      ListWavFilesInDir(actual_files_dir);<br /><br />  AnalyzeSegmentsAndPrintResult(<br />      ref_segments, actual_segments, reference_file, perf_modifier);<br /><br />  DeleteFileUnlessTestFailed(recording, <span>false</span>);<br />  DeleteFileUnlessTestFailed(actual_files_dir, <span>true</span>);</pre><br />Where AnalyzeSegmentsAndPrintResult looks like this:  <br /><br /><pre><span>void</span> AnalyzeSegmentsAndPrintResult(<br /><span>const</span> std::<span>vector</span>&#60;base::FilePath&#62;&#38; ref_segments,<br /><span>const</span> std::<span>vector</span>&#60;base::FilePath&#62;&#38; actual_segments,<br /><span>const</span> base::FilePath&#38; reference_file,<br /><span>const</span> std::<span>string</span>&#38; perf_modifier) {<br />  ASSERT_GT(ref_segments.size(), 0u)<br />      &#60;&#60; <span>"Failed to split reference file on silence; sox is likely broken."</span>;<br />  ASSERT_EQ(ref_segments.size(), actual_segments.size())<br />      &#60;&#60; <span>"The recording did not result in the same number of audio segments "</span><br />      &#60;&#60; <span>"after on splitting on silence; WebRTC must have deformed the audio "</span><br />      &#60;&#60; <span>"too much."</span>;<br /><br /><span>for</span> (size_t i = 0; i &#60; ref_segments.size(); i++) {<br /><span>float</span> difference_in_decibel = AnalyzeOneSegment(ref_segments[i],<br />                                                    actual_segments[i],<br />                                                    i);<br />    std::<span>string</span> trace_name = MakeTraceName(reference_file, i);<br />    perf_test::PrintResult(<span>"agc_energy_diff"</span>, perf_modifier, trace_name,<br />                           difference_in_decibel, <span>"dB"</span>, <span>false</span>);<br />  }<br />}<br /></pre><br />The results look like <a href="https://chromeperf.appspot.com/report">this</a>:  <br /><br /><div><a href="http://2.bp.blogspot.com/-9-d447SeI5o/VhaQfM5BgGI/AAAAAAAAAMQ/Vi_3bfPacRU/s1600/image02.png"><img border="0" height="321" src="http://2.bp.blogspot.com/-9-d447SeI5o/VhaQfM5BgGI/AAAAAAAAAMQ/Vi_3bfPacRU/s640/image02.png" width="640"></a></div><div><i>Figure 6. Average Adiff values for each segment on the y axis, Chromium revisions on the x axis.</i></div><br />We can clearly see the AGC applies about 6 dB of gain to the (relatively low-energy) audio file we feed in. The maximum amount of gain the digital AGC can apply is 12 dB, and 7 dB is the default, so in this case the AGC is pretty happy with the level of the input audio. If we run with the AGC turned off, we get the expected 0 dB of gain. The diff varies a bit per segment, since the segments are different in audio power. <br /><br />Using this test, we can detect if the AGC accidentally gets turned off or malfunctions on windows, mac or linux. If that happens, the with_agc graph will drop from ~6 db to 0, and we&#8217;ll know something is up. Same thing if the amount of digital gain changes. <br /><br />A more advanced version of this test would also look at the mic level the AGC sets. This mic level is currently ignored in the test, but it could take it into account by artificially amplifying the reference file when played through the fake device. We could also try throwing curveballs at the AGC, like abruptly raising the volume mid-test (as if the user leaned closer to the mic), and look at the gain for the segments to ensure it adapted correctly. <br /><br />]]></description>
				<content:encoded><![CDATA[<i>By: Patrik Höglund </i><br /><br /><h2>What is Automatic Gain Control?&nbsp;</h2>It’s time to talk about advanced media quality tests again! As experienced Google testing blog readers know, when I write an article it’s usually about WebRTC, and the unusual testing solutions we build to test it. This article is no exception. Today we’re going to talk about Automatic Gain Control, or AGC. This is a feature that’s on by default for WebRTC applications, such as <a href="http://apprtc.appspot.com/">http://apprtc.appspot.com</a>. It uses various means to adjust the microphone signal so your voice makes it loud and clear to the other side of the peer connection. For instance, it can attempt to adjust your microphone gain or try to amplify the signal digitally.<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-gTvHr_vpehs/VhaQZ78-y5I/AAAAAAAAAL0/Z4BAXUNDNcU/s1600/image03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="336" src="http://3.bp.blogspot.com/-gTvHr_vpehs/VhaQZ78-y5I/AAAAAAAAAL0/Z4BAXUNDNcU/s640/image03.png" width="640" /></a></div><div style="text-align: center;"><i>Figure 1. How Auto Gain Control works [<a href="https://code.google.com/p/chromium/codesearch#chromium/src/third_party/webrtc/modules/audio_processing/agc/agc_manager_direct.h&amp;sq=package:chromium">code here</a>]. </i></div><div style="text-align: center;"><br /></div>This is an example of automatic control engineering (another example would be the classic <a href="https://en.wikipedia.org/wiki/PID_controller">PID controller</a>) and happens in real time. Therefore, if you move closer to the mic while speaking, the AGC will notice the output stream is too loud, and reduce mic volume and/or digital gain. When you move further away, it tries to adapt up again. The fancy voice activity detector is there so we only amplify speech, and not, say, the microwave oven your spouse just started in the other room.<br /><h2>Testing the AGC</h2>Now, how do we make sure the AGC works? The first thing is obviously to <a href="https://code.google.com/p/chromium/codesearch#chromium/src/third_party/webrtc/modules/audio_processing/agc/agc_unittest.cc&amp;sq=package:chromium">write unit tests</a> and <a href="https://code.google.com/p/chromium/codesearch#chromium/src/third_party/webrtc/modules/audio_processing/test/">integration tests</a>. You <a href="http://googletesting.blogspot.com/2015/04/just-say-no-to-more-end-to-end-tests.html">didn’t think about building that end-to-end test first, did you</a>? Once we have the lower-level tests in place, we can start looking at a bigger test. While developing the WebRTC implementation in Chrome, we had several bugs where the AGC code was working by itself, but was misconfigured in Chrome. In one case, it was simply turned off for all users. In another, it was only turned off in Hangouts.  <br /><br />Only an end-to-end test can catch these integration issues, and we already had <a href="http://googletesting.blogspot.com/2013/11/webrtc-audio-quality-testing.html">stable, low-maintenance audio quality tests</a> with the ability to record Chrome’s output sound for analysis. I encourage you to read that article, but the bottom line is that those tests can run a WebRTC call in two tabs and record the audio output to a file. Those tests run the <a href="https://en.wikipedia.org/wiki/PESQ">PESQ</a> algorithm on input and output to see how similar they are. <br /><br />That’s a good framework to have, but I needed to make two changes:<br /><br /><ul><li>Add file support to Chrome’s fake audio input device, so we can play a known file. The original audio test avoided this by using WebAudio, but AGC doesn’t run in the WebAudio path, just the microphone capture path, so that won’t work.</li><li>Instead of running PESQ, run an analysis that compares the gain between input and output.</li></ul><h2>Adding Fake File Support</h2>This is always a big part of the work in media testing: controlling the input and output. It’s unworkable to tape microphones to loudspeakers or point cameras to screens to capture the media, so the easiest solution is usually to add a debug flag. It is exactly what I did <a href="https://code.google.com/p/chromium/codesearch#chromium/src/media/audio/fake_audio_input_stream.cc&amp;sq=package:chromium&amp;type=cs&amp;rcl=1443324274&amp;l=118">here</a>. It was a lot of work, but I won’t go into much detail since Chrome’s audio pipeline is complex. The core is <a href="https://code.google.com/p/chromium/codesearch#chromium/src/media/audio/simple_sources.cc&amp;sq=package:chromium&amp;type=cs">this</a>: <br /><br /><pre style="background: #d6d6d6; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;"><span style="color: #0433ff;">int</span> FileSource::OnMoreData(AudioBus* audio_bus, uint32 total_bytes_delay) {<br />  <span style="color: #4f8f00;">// Load the file if we haven't already. This load needs to happen on the</span><br />  <span style="color: #4f8f00;">// audio thread, otherwise we'll run on the UI thread on Mac for instance.</span><br />  <span style="color: #4f8f00;">// This will massively delay the first OnMoreData, but we'll catch up.</span><br />  <span style="color: #0433ff;">if</span> (!wav_audio_handler_)<br />    LoadWavFile(path_to_wav_file_);<br />  <span style="color: #0433ff;">if</span> (load_failed_)<br />    <span style="color: #0433ff;">return</span> 0;<br /><br />  DCHECK(wav_audio_handler_.get());<br /><br />  <span style="color: #4f8f00;">// Stop playing if we've played out the whole file.</span><br />  <span style="color: #0433ff;">if</span> (wav_audio_handler_-&gt;AtEnd(wav_file_read_pos_))<br />    <span style="color: #0433ff;">return</span> 0;<br /><br />  <span style="color: #4f8f00;">// This pulls data from ProvideInput.</span><br />  file_audio_converter_-&gt;Convert(audio_bus);<br />  <span style="color: #0433ff;">return</span> audio_bus-&gt;frames();<br />}<br /></pre><br />This code runs every 10 ms and reads a small chunk from the file, converts it to Chrome’s preferred audio format and sends it on through the audio pipeline. After implementing this, I could simply run: <br /><br /><pre style="background: #d6d6d6; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;">chrome --use-fake-device-for-media-stream <br />       --use-file-for-fake-audio-capture=/tmp/file.wav<br /></pre><br />and whenever I hit a webpage that used WebRTC, the above file would play instead of my microphone input. Sweet!<br /><h2>The Analysis Stage</h2>Next I had to get the analysis stage figured out. It turned out there was something called an <a href="https://code.google.com/p/chromium/codesearch#chromium/src/media/audio/audio_power_monitor.h&amp;q=audiopowermo&amp;sq=package:chromium&amp;l=36">AudioPowerMonitor</a> in the Chrome code, which you feed audio data into and get the average audio power for the data you fed in. This is a measure of how “loud” the audio is. Since the whole point of the AGC is getting to the right audio power level, we’re looking to compute<br /><br /><i>A<sub>diff</sub> = A<sub>out</sub> - A<sub>in</sub></i><br /><br />Or, really, how much louder or weaker is the output compared to the input audio? Then we can construct different scenarios: <i>A<sub>diff</sub></i> should be 0 if the AGC is turned off and it should be &gt; 0 dB if the AGC is on and we feed in a low power audio file. Computing the average energy of an audio file was straightforward to <a href="https://code.google.com/p/chromium/codesearch#chromium/src/chrome/browser/media/webrtc_browsertest_audio.cc&amp;sq=package:chromium&amp;type=cs&amp;l=56">implement</a>: <br /><br /><pre style="background: #d6d6d6; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;">  <span style="color: #4f8f00;">// ...</span><br />  size_t bytes_written;<br />  wav_audio_handler-&gt;CopyTo(audio_bus.get(), 0, &amp;bytes_written);<br />  CHECK_EQ(bytes_written, wav_audio_handler-&gt;data().size())<br />      &lt;&lt; <span style="color: #ff2600;">"Expected to write entire file into bus."</span>;<br /><br />  <span style="color: #4f8f00;">// Set the filter coefficient to the whole file's duration; this will make</span><br />  <span style="color: #4f8f00;">// the power monitor take the entire file into account.</span><br />  media::AudioPowerMonitor power_monitor(wav_audio_handler-&gt;sample_rate(),<br />                                         file_duration);<br />  power_monitor.Scan(*audio_bus, audio_bus-&gt;frames());<br />  <span style="color: #4f8f00;">// ...</span><br />  <span style="color: #0433ff;">return</span> power_monitor.ReadCurrentPowerAndClip().first;</pre><br />I wrote a new test, and hooked up the above logic instead of PESQ. I could compute&nbsp;<i>A<sub>in</sub></i>&nbsp;by running the above algorithm on the reference file (which I fed in using the flag I implemented above) and <i>A<sub>out</sub></i> on the recording of the output audio. At this point I pretty much thought I was done. I ran a WebRTC call with the AGC turned off, expecting to get zero… and got a huge number. Turns out I wasn’t done.<br /><h2>What Went Wrong?</h2>I needed more debugging information to figure out what went wrong. Since the AGC was off, I would expect the power curves for output and input to be identical. All I had was the average audio power over the entire file, so I started plotting the audio power for each 10 millisecond segment instead to understand where the curves diverged. I could then plot the detected audio power over the time of the test. I started by plotting <i>A<sub>diff&nbsp;</sub></i>: <br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-DjKeQ5-Bh24/VhaQdgGzpaI/AAAAAAAAAMI/Rpr3raMc0F4/s1600/image01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="161" src="http://1.bp.blogspot.com/-DjKeQ5-Bh24/VhaQdgGzpaI/AAAAAAAAAMI/Rpr3raMc0F4/s640/image01.png" width="640" /></a></div><div style="text-align: center;"><i>Figure 2. Plot of A<sub>diff</sub>.</i></div><br />The difference is quite small in the beginning, but grows in amplitude over time. Interesting. I then plotted <i>A<sub>out</sub></i> and <i>A<sub>in</sub></i> next to each other:  <br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-32eITCuxF1c/VhaQbhizILI/AAAAAAAAAMA/FuRSRd2-2ek/s1600/image00.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="249" src="http://4.bp.blogspot.com/-32eITCuxF1c/VhaQbhizILI/AAAAAAAAAMA/FuRSRd2-2ek/s640/image00.png" width="640" /></a></div><div style="text-align: center;"><i>Figure 3. Plot of&nbsp;A<sub>out&nbsp;</sub>and&nbsp;A<sub>in</sub>.</i></div><br />A-ha! The curves drift apart over time; the above shows about 10 seconds of time, and the drift is maybe 80 ms at the end. The more they drift apart, the bigger the diff becomes. Exasperated, I asked our audio engineers about the above. Had my fancy test found its first bug? No, as it turns out - it was by design.<br /><h2>Clock Drift and Packet Loss</h2>Let me explain. As a part of WebRTC audio processing, we run a complex module called <a href="https://code.google.com/p/chromium/codesearch#chromium/src/third_party/webrtc/modules/audio_coding/neteq/&amp;q=neteq&amp;sq=package:chromium">NetEq</a> on the received audio stream. When sending audio over the Internet, there will inevitably be <i>packet loss</i> and <i>clock drift</i>. Packet losses always happen on the Internet, depending on the network path between sender and receiver. Clock drift happens because the sample clocks on the sending and receiving sound cards are not perfectly synced. <br /><br />In this particular case, the problem was not packet loss since we have ideal network conditions (one machine, packets go over the machine’s loopback interface = zero packet loss). But how can we have clock drift? Well, recall the fake device I wrote earlier that reads a file? It never touches the sound card like when the sound comes from the mic, so it runs on the system clock. That clock will drift against the machine’s sound card clock, even when we are on the same machine.  <br /><br />NetEq uses clever algorithms to conceal clock drift and packet loss. Most commonly it applies time compression or stretching on the audio it plays out, which means it makes the audio a little shorter or longer when needed to compensate for the drift. We humans mostly don’t even notice that, whereas a drift left uncompensated would result in a depleted or flooded receiver buffer – very noticeable. Anyway, I digress. This drift of the recording vs. the reference file was natural and I would just have to deal with it.<br /><h2>Silence Splitting to the Rescue!</h2>I could probably have solved this with math and postprocessing of the results (<a href="https://en.wikipedia.org/wiki/Least_squares">least squares</a>  maybe?), but I had another idea. The reference file happened to be comprised of five segments with small pauses between them. What if I made these pauses longer, split the files on the pauses and trimmed away all the silence? This would effectively align the start of each segment with its corresponding segment in the reference file.  <br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-dsxRyso4oLE/VhaQiGyCxUI/AAAAAAAAAMg/TLldcn7OYek/s1600/image05.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="112" src="http://2.bp.blogspot.com/-dsxRyso4oLE/VhaQiGyCxUI/AAAAAAAAAMg/TLldcn7OYek/s640/image05.png" width="640" /></a></div><div style="text-align: center;"><i>Figure 4. Before silence splitting.</i></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-Z0MlHuMC4pI/VhaQg2cK-FI/AAAAAAAAAMY/m7jCmlRmnJU/s1600/image04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="176" src="http://1.bp.blogspot.com/-Z0MlHuMC4pI/VhaQg2cK-FI/AAAAAAAAAMY/m7jCmlRmnJU/s640/image04.png" width="640" /></a></div><div style="text-align: center;"><i>Figure 5. After silence splitting.</i></div><br />We would still have NetEQ drift, but as you can see its effects will not stack up towards the end, so if the segments are short enough we should be able to mitigate this problem.<br /><h2>Result</h2>Here is the <a href="https://code.google.com/p/chromium/codesearch#chromium/src/chrome/browser/media/chrome_webrtc_audio_quality_browsertest.cc">final test implementation</a>:  <br /><br /><pre style="background: #d6d6d6; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;">  base::FilePath reference_file = <br />      test::GetReferenceFilesDir().Append(reference_filename);<br />  base::FilePath recording = CreateTemporaryWaveFile();<br /><br />  ASSERT_NO_FATAL_FAILURE(SetupAndRecordAudioCall(<br />      reference_file, recording, constraints,<br />      base::TimeDelta::FromSeconds(30)));<br /><br />  base::ScopedTempDir split_ref_files;<br />  ASSERT_TRUE(split_ref_files.CreateUniqueTempDir());<br />  ASSERT_NO_FATAL_FAILURE(<br />      SplitFileOnSilenceIntoDir(reference_file, split_ref_files.path()));<br />  std::<span style="color: #0433ff;">vector</span>&lt;base::FilePath&gt; ref_segments =<br />      ListWavFilesInDir(split_ref_files.path());<br /><br />  base::ScopedTempDir split_actual_files;<br />  ASSERT_TRUE(split_actual_files.CreateUniqueTempDir());<br />  ASSERT_NO_FATAL_FAILURE(<br />      SplitFileOnSilenceIntoDir(recording, split_actual_files.path()));<br /><br />  <span style="color: #4f8f00;">// Keep the recording and split files if the analysis fails.</span><br />  base::FilePath actual_files_dir = split_actual_files.Take();<br />  std::<span style="color: #0433ff;">vector</span>&lt;base::FilePath&gt; actual_segments =<br />      ListWavFilesInDir(actual_files_dir);<br /><br />  AnalyzeSegmentsAndPrintResult(<br />      ref_segments, actual_segments, reference_file, perf_modifier);<br /><br />  DeleteFileUnlessTestFailed(recording, <span style="color: #0433ff;">false</span>);<br />  DeleteFileUnlessTestFailed(actual_files_dir, <span style="color: #0433ff;">true</span>);</pre><br />Where AnalyzeSegmentsAndPrintResult looks like this:  <br /><br /><pre style="background: #d6d6d6; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;"><span style="color: #0433ff;">void</span> AnalyzeSegmentsAndPrintResult(<br />    <span style="color: #0433ff;">const</span> std::<span style="color: #0433ff;">vector</span>&lt;base::FilePath&gt;&amp; ref_segments,<br />    <span style="color: #0433ff;">const</span> std::<span style="color: #0433ff;">vector</span>&lt;base::FilePath&gt;&amp; actual_segments,<br />    <span style="color: #0433ff;">const</span> base::FilePath&amp; reference_file,<br />    <span style="color: #0433ff;">const</span> std::<span style="color: #0433ff;">string</span>&amp; perf_modifier) {<br />  ASSERT_GT(ref_segments.size(), 0u)<br />      &lt;&lt; <span style="color: #ff2600;">"Failed to split reference file on silence; sox is likely broken."</span>;<br />  ASSERT_EQ(ref_segments.size(), actual_segments.size())<br />      &lt;&lt; <span style="color: #ff2600;">"The recording did not result in the same number of audio segments "</span><br />      &lt;&lt; <span style="color: #ff2600;">"after on splitting on silence; WebRTC must have deformed the audio "</span><br />      &lt;&lt; <span style="color: #ff2600;">"too much."</span>;<br /><br />  <span style="color: #0433ff;">for</span> (size_t i = 0; i &lt; ref_segments.size(); i++) {<br />    <span style="color: #0433ff;">float</span> difference_in_decibel = AnalyzeOneSegment(ref_segments[i],<br />                                                    actual_segments[i],<br />                                                    i);<br />    std::<span style="color: #0433ff;">string</span> trace_name = MakeTraceName(reference_file, i);<br />    perf_test::PrintResult(<span style="color: #ff2600;">"agc_energy_diff"</span>, perf_modifier, trace_name,<br />                           difference_in_decibel, <span style="color: #ff2600;">"dB"</span>, <span style="color: #0433ff;">false</span>);<br />  }<br />}<br /></pre><br />The results look like <a href="https://chromeperf.appspot.com/report">this</a>:  <br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-9-d447SeI5o/VhaQfM5BgGI/AAAAAAAAAMQ/Vi_3bfPacRU/s1600/image02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="321" src="http://2.bp.blogspot.com/-9-d447SeI5o/VhaQfM5BgGI/AAAAAAAAAMQ/Vi_3bfPacRU/s640/image02.png" width="640" /></a></div><div style="text-align: center;"><i>Figure 6. Average Adiff values for each segment on the y axis, Chromium revisions on the x axis.</i></div><br />We can clearly see the AGC applies about 6 dB of gain to the (relatively low-energy) audio file we feed in. The maximum amount of gain the digital AGC can apply is 12 dB, and 7 dB is the default, so in this case the AGC is pretty happy with the level of the input audio. If we run with the AGC turned off, we get the expected 0 dB of gain. The diff varies a bit per segment, since the segments are different in audio power. <br /><br />Using this test, we can detect if the AGC accidentally gets turned off or malfunctions on windows, mac or linux. If that happens, the with_agc graph will drop from ~6 db to 0, and we’ll know something is up. Same thing if the amount of digital gain changes. <br /><br />A more advanced version of this test would also look at the mic level the AGC sets. This mic level is currently ignored in the test, but it could take it into account by artificially amplifying the reference file when played through the fake device. We could also try throwing curveballs at the AGC, like abruptly raising the volume mid-test (as if the user leaned closer to the mic), and look at the gain for the segments to ensure it adapted correctly. <br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/audio-testing-automatic-gain-control/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>The Deadline to Apply for GTAC 2015 is Monday Aug 10</title>
		<link>https://googledata.org/google-testing/the-deadline-to-apply-for-gtac-2015-is-monday-aug-10/</link>
		<comments>https://googledata.org/google-testing/the-deadline-to-apply-for-gtac-2015-is-monday-aug-10/#comments</comments>
		<pubDate>Fri, 07 Aug 2015 17:33:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=548769f9b837fb4de026c7f565b4101c</guid>
		<description><![CDATA[<i>Posted by <a href="http://anthonyvallone.com/">Anthony Vallone</a> on behalf of the GTAC Committee  </i><br /><br /><div><a href="http://3.bp.blogspot.com/-u-xjf3fpfKU/VcTqhZwpQqI/AAAAAAAAALE/lPHaxZyyGiM/s1600/gtac-small.png"><img border="0" src="https://3.bp.blogspot.com/-u-xjf3fpfKU/VcTqhZwpQqI/AAAAAAAAALE/lPHaxZyyGiM/s1600/gtac-small.png"></a></div><br />The deadline to apply for GTAC 2015 is this Monday, August 10th, 2015. There is a great deal of interest to both attend and speak, and we&#8217;ve received many outstanding proposals. However, it&#8217;s not too late to submit your proposal for consideration. If you would like to speak or attend, be sure to <a href="https://docs.google.com/a/google.com/forms/d/1fEByEl11ixnZ8U-fd_iwJgs4tt5eGPIPisLLRWMiBK0/viewform">complete the form</a> by Monday.  <br /><br />We will be making regular updates to the GTAC site (<a href="http://developers.google.com/gtac/2015">developers.google.com/gtac/2015/</a>) over the next several weeks, and you can find conference details there. <br /><br />For those that have already signed up to attend or speak, we will contact you directly by mid-September. <br /><br />]]></description>
				<content:encoded><![CDATA[<i>Posted by <a href="http://anthonyvallone.com/">Anthony Vallone</a> on behalf of the GTAC Committee  </i><br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-u-xjf3fpfKU/VcTqhZwpQqI/AAAAAAAAALE/lPHaxZyyGiM/s1600/gtac-small.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://3.bp.blogspot.com/-u-xjf3fpfKU/VcTqhZwpQqI/AAAAAAAAALE/lPHaxZyyGiM/s1600/gtac-small.png" /></a></div><br />The deadline to apply for GTAC 2015 is this Monday, August 10th, 2015. There is a great deal of interest to both attend and speak, and we’ve received many outstanding proposals. However, it’s not too late to submit your proposal for consideration. If you would like to speak or attend, be sure to <a href="https://docs.google.com/a/google.com/forms/d/1fEByEl11ixnZ8U-fd_iwJgs4tt5eGPIPisLLRWMiBK0/viewform">complete the form</a> by Monday.  <br /><br />We will be making regular updates to the GTAC site (<a href="http://developers.google.com/gtac/2015">developers.google.com/gtac/2015/</a>) over the next several weeks, and you can find conference details there. <br /><br />For those that have already signed up to attend or speak, we will contact you directly by mid-September. <br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/the-deadline-to-apply-for-gtac-2015-is-monday-aug-10/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>GTAC 2015: Call for Proposals &amp; Attendance</title>
		<link>https://googledata.org/google-testing/gtac-2015-call-for-proposals-attendance/</link>
		<comments>https://googledata.org/google-testing/gtac-2015-call-for-proposals-attendance/#comments</comments>
		<pubDate>Tue, 30 Jun 2015 21:11:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=9d5acdc48b906e976e7070bd28bf8c07</guid>
		<description><![CDATA[<i>Posted by <a href="http://anthonyvallone.com/">Anthony Vallone</a> on behalf of the GTAC Committee </i><br /><br />The GTAC (Google Test Automation Conference) 2015 application process is now open for presentation proposals and attendance. GTAC will be held at the <a href="https://www.google.com/about/careers/locations/cambridge/">Google Cambridge office</a> (near Boston, Massachusetts, USA) on November 10th - 11th, 2015. <br /><br />GTAC will be streamed live on YouTube again this year, so even if you can&#8217;t attend in person, you&#8217;ll be able to watch the conference remotely. We will post the live stream information as we get closer to the event, and recordings will be posted afterward. <br /><br /><b>Speakers</b><br />Presentations are targeted at student, academic, and experienced engineers working on test automation. Full presentations are 30 minutes and lightning talks are 10 minutes. Speakers should be prepared for a question and answer session following their presentation. <br /><br /><b>Application</b><br />For presentation proposals and/or attendance, <a href="https://docs.google.com/a/google.com/forms/d/1fEByEl11ixnZ8U-fd_iwJgs4tt5eGPIPisLLRWMiBK0/viewform">complete this form</a>. We will be selecting about 25 talks and 200 attendees for the event. The selection process is not first come first serve (no need to rush your application), and we select a diverse group of engineers from various locations, company sizes, and technical backgrounds (academic, industry expert, junior engineer, etc). <br /><br /><b>Deadline</b><br />The due date for both presentation and attendance applications is August 10th, 2015. <br /><br /><b>Fees</b><br />There are no registration fees, but speakers and attendees must arrange and pay for their own travel and accommodations. <br /><br /><b>More information</b><br />You can find more details at <a href="http://developers.google.com/gtac">developers.google.com/gtac</a>. <br /><br />]]></description>
				<content:encoded><![CDATA[<i>Posted by <a href="http://anthonyvallone.com/">Anthony Vallone</a> on behalf of the GTAC Committee </i><br /><br />The GTAC (Google Test Automation Conference) 2015 application process is now open for presentation proposals and attendance. GTAC will be held at the <a href="https://www.google.com/about/careers/locations/cambridge/">Google Cambridge office</a> (near Boston, Massachusetts, USA) on November 10th - 11th, 2015. <br /><br />GTAC will be streamed live on YouTube again this year, so even if you can’t attend in person, you’ll be able to watch the conference remotely. We will post the live stream information as we get closer to the event, and recordings will be posted afterward. <br /><br /><b>Speakers</b><br />Presentations are targeted at student, academic, and experienced engineers working on test automation. Full presentations are 30 minutes and lightning talks are 10 minutes. Speakers should be prepared for a question and answer session following their presentation. <br /><br /><b>Application</b><br />For presentation proposals and/or attendance, <a href="https://docs.google.com/a/google.com/forms/d/1fEByEl11ixnZ8U-fd_iwJgs4tt5eGPIPisLLRWMiBK0/viewform">complete this form</a>. We will be selecting about 25 talks and 200 attendees for the event. The selection process is not first come first serve (no need to rush your application), and we select a diverse group of engineers from various locations, company sizes, and technical backgrounds (academic, industry expert, junior engineer, etc). <br /><br /><b>Deadline</b><br />The due date for both presentation and attendance applications is August 10th, 2015. <br /><br /><b>Fees</b><br />There are no registration fees, but speakers and attendees must arrange and pay for their own travel and accommodations. <br /><br /><b>More information</b><br />You can find more details at <a href="http://developers.google.com/gtac">developers.google.com/gtac</a>. <br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/gtac-2015-call-for-proposals-attendance/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>GTAC 2015 Coming to Cambridge (Greater Boston) in November</title>
		<link>https://googledata.org/google-testing/gtac-2015-coming-to-cambridge-greater-boston-in-november/</link>
		<comments>https://googledata.org/google-testing/gtac-2015-coming-to-cambridge-greater-boston-in-november/#comments</comments>
		<pubDate>Thu, 28 May 2015 16:56:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=003e13a959c4bac9e91f6376d5fa725e</guid>
		<description><![CDATA[<i>Posted by <a href="http://anthonyvallone.com/">Anthony Vallone</a> on behalf of the GTAC Committee </i><br /><br /><div><a href="http://1.bp.blogspot.com/-EdrZ3m_reY8/VWdG5_ROrSI/AAAAAAAAAKw/mt03BB6n9PE/s1600/gtac-colored-letters.png"><img border="0" height="106" src="https://1.bp.blogspot.com/-EdrZ3m_reY8/VWdG5_ROrSI/AAAAAAAAAKw/mt03BB6n9PE/s320/gtac-colored-letters.png" width="320"></a></div><br />We are pleased to announce that the ninth GTAC (Google Test Automation Conference) will be held in <a href="https://www.google.com/about/careers/locations/cambridge/">Cambridge</a> (Greatah Boston, USA) on November 10th and 11th (<a href="http://en.wikipedia.org/wiki/Boston_accent">Toozdee and Wenzdee</a>), 2015. So, tell everyone to save the date for this wicked good event. <br /><br />GTAC is an annual conference hosted by Google, bringing together engineers from industry and academia to discuss advances in test automation and the test engineering computer science field. It&#8217;s a great opportunity to present, learn, and challenge modern testing technologies and strategies. <br /><br />You can browse presentation abstracts, slides, and videos from previous years on the <a href="https://developers.google.com/google-test-automation-conference/">GTAC</a> site.  <br /><br />Stay tuned to this blog and the GTAC website for application information and opportunities to present at GTAC. Subscribing to this blog is the best way to get notified. We're looking forward to seeing you there!  <br /><br />]]></description>
				<content:encoded><![CDATA[<i>Posted by <a href="http://anthonyvallone.com/">Anthony Vallone</a> on behalf of the GTAC Committee </i><br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-EdrZ3m_reY8/VWdG5_ROrSI/AAAAAAAAAKw/mt03BB6n9PE/s1600/gtac-colored-letters.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="106" src="https://1.bp.blogspot.com/-EdrZ3m_reY8/VWdG5_ROrSI/AAAAAAAAAKw/mt03BB6n9PE/s320/gtac-colored-letters.png" width="320" /></a></div><br />We are pleased to announce that the ninth GTAC (Google Test Automation Conference) will be held in <a href="https://www.google.com/about/careers/locations/cambridge/">Cambridge</a> (Greatah Boston, USA) on November 10th and 11th (<a href="http://en.wikipedia.org/wiki/Boston_accent">Toozdee and Wenzdee</a>), 2015. So, tell everyone to save the date for this wicked good event. <br /><br />GTAC is an annual conference hosted by Google, bringing together engineers from industry and academia to discuss advances in test automation and the test engineering computer science field. It’s a great opportunity to present, learn, and challenge modern testing technologies and strategies. <br /><br />You can browse presentation abstracts, slides, and videos from previous years on the <a href="https://developers.google.com/google-test-automation-conference/">GTAC</a> site.  <br /><br />Stay tuned to this blog and the GTAC website for application information and opportunities to present at GTAC. Subscribing to this blog is the best way to get notified. We're looking forward to seeing you there!  <br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/gtac-2015-coming-to-cambridge-greater-boston-in-november/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Multi-Repository Development</title>
		<link>https://googledata.org/google-testing/multi-repository-development/</link>
		<comments>https://googledata.org/google-testing/multi-repository-development/#comments</comments>
		<pubDate>Fri, 15 May 2015 20:53:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=bb39f600c0319cdf6b3314979d9bd9dd</guid>
		<description><![CDATA[<i>Author: Patrik H&#246;glund </i><br /><br />As we all know, software development is a complicated activity where we develop features and applications to provide value to our users. Furthermore, any nontrivial modern software is composed out of other software. For instance, the Chrome web browser pulls <a href="https://code.google.com/p/chromium/codesearch#chromium/src/third_party/&#38;sq=package:chromium">roughly a hundred libraries</a> into its third_party folder when you build the browser. The most significant of these libraries is Blink, the rendering engine, but there&#8217;s also ffmpeg for image processing, skia for low-level 2D graphics, and WebRTC for real-time communication (to name a few). <br /><br /><div><a href="http://4.bp.blogspot.com/-6nJYH4SDvFc/VVZVadP56QI/AAAAAAAAAKQ/oEJRo9rro_s/s1600/image01.png"><img border="0" src="http://4.bp.blogspot.com/-6nJYH4SDvFc/VVZVadP56QI/AAAAAAAAAKQ/oEJRo9rro_s/s1600/image01.png"></a></div><div><i>Figure 1. Holy dependencies, Batman!</i></div><br />There are many reasons to use software libraries. Why write your own phone number parser when you can use <a href="https://github.com/googlei18n/libphonenumber">libphonenumber</a>, which is battle-tested by real use in Android and Chrome and available under a permissive license? Using such software frees you up to focus on the core of your software so you can deliver a unique experience to your users. On the other hand, you need to keep your application up to date with changes in the library (you want that latest bug fix, right?), and you also run a risk of such a change breaking your application. This article will examine that integration problem and how you can reduce the risks associated with it.<br /><h2>Updating Dependencies is Hard</h2>The simplest solution is to check in a copy of the library, build with it, and avoid touching it as much as possible. This solution, however, can be problematic because you miss out on bug fixes and new features in the library. What if you need a new feature or bug fix that just made it in? You have a few options:<br /><ul><li>Update the library to its latest release. If it&#8217;s been a long time since you did this, it can be quite risky and you may have to spend significant testing resources to ensure all the accumulated changes don&#8217;t break your application. You may have to catch up to interface changes in the library as well.&#160;</li><li>Cherry-pick the feature/bug fix you want into your copy of the library. This is even riskier because your cherry-picked patches may depend on other changes in the library in subtle ways. Also, you still are not up to date with the latest version.&#160;</li><li>Find some way to make do without the feature or bug fix.</li></ul>None of the above options are very good. Using this ad-hoc updating model can work if there&#8217;s a low volume of changes in the library and our requirements on the library don&#8217;t change very often. Even if that is the case, what will you do if a critical zero-day exploit is discovered in your socket library?  <br /><br />One way to mitigate the update risk is to integrate more often with your dependencies. As an extreme example, let&#8217;s look at Chrome. <br /><br />In Chrome development, there&#8217;s a massive amount of change going into its dependencies. The Blink rendering engine lives in a separate code repository from the browser. Blink sees hundreds of code changes per day, and Chrome must integrate with Blink often since it&#8217;s an important part of the browser. Another example is the WebRTC implementation, where a large part of Chrome&#8217;s implementation resides in the webrtc.org repository. This article will focus on the latter because it&#8217;s the team I happen to work on.<br /><h2>How &#8220;Rolling&#8221; Works&#160;</h2>The open-sourced WebRTC codebase is used by Chrome but also by a number of other companies working on WebRTC. Chrome uses a toolchain called depot_tools to manage dependencies, and there&#8217;s a checked-in text file called <a href="https://code.google.com/p/chromium/codesearch#chromium/src/DEPS&#38;q=DEPS&#38;sq=package:chromium&#38;l=1">DEPS</a> where dependencies are managed. It looks roughly like this:<br /><pre>{<br /><span># ... </span><br /><span>'src/third_party/webrtc'</span>:<br /><span>'https://chromium.googlesource.com/'</span> +<br /><span>'external/webrtc/trunk/webrtc.git'</span> + <br /><span>'@'</span> + <span>'5727038f572c517204e1642b8bc69b25381c4e9f'</span>,<br />}<br /></pre><br />The above means we should pull WebRTC from the specified git repository at the <span>572703...</span> hash, similar to other dependency-provisioning frameworks. To build Chrome with a new version, we change the hash and check in a new version of the <a href="https://code.google.com/p/chromium/codesearch#chromium/src/DEPS&#38;q=DEPS&#38;sq=package:chromium&#38;l=1">DEPS</a> file. If the library&#8217;s API has changed, we must update Chrome to use the new API in the same patch. This process is known as <i>rolling</i> WebRTC to a new version. <br /><br />Now the problem is that we have changed the code going into Chrome. Maybe <a href="https://code.google.com/p/chromium/issues/detail?id=430001">getUserMedia has started crashing on Android</a>, or maybe the browser no longer boots on Windows. We don&#8217;t know until we have built and run all the tests. Therefore a roll patch is subject to the same presubmit checks as any Chrome patch (i.e. <a href="https://www.chromium.org/developers/testing/try-server-usage">many tests, on all platforms we ship on</a>). However, roll patches can be considerably more painful and risky than other patches. <br /><br /><br /><div><a href="http://3.bp.blogspot.com/-GWwsqyYm43c/VVZVf_WpvvI/AAAAAAAAAKY/qhlMLTB6nbA/s1600/image00.png"><img border="0" src="http://3.bp.blogspot.com/-GWwsqyYm43c/VVZVf_WpvvI/AAAAAAAAAKY/qhlMLTB6nbA/s1600/image00.png"></a></div><div><i>Figure 2. Life of a Roll Patch.</i></div><br />On the WebRTC team we found ourselves in an uncomfortable position a couple years back. Developers would make changes to the webrtc.org code and there was a fair amount of churn in the interface, which meant we would have to update Chrome to adapt to those changes. Also we frequently broke tests and WebRTC functionality in Chrome because semantic changes had unexpected consequences in Chrome. Since rolls were so risky and painful to make, they started to happen less often, which made things even worse. There could be two weeks between rolls, which meant Chrome was hit by a large number of changes in one patch.<br /><h2>Bots That Can See the Future: &#8220;FYI Bots&#8221;&#160;</h2>We found a way to mitigate this which we called FYI (for your information) bots. A bot is Chrome lingo for a continuous build machine which builds Chrome and runs tests. <br /><br />All the existing Chrome bots at that point would build Chrome as specified in the <a href="https://code.google.com/p/chromium/codesearch#chromium/src/DEPS&#38;q=DEPS&#38;sq=package:chromium&#38;l=1">DEPS</a> file, which meant they would build the WebRTC version we had rolled to up to that point. FYI bots replace that pinned version with WebRTC HEAD, but otherwise build and run Chrome-level tests as usual. Therefore:  <br /><br /><ul><li>If all the FYI bots were green, we knew a roll most likely would go smoothly.&#160;</li><li>If the bots didn&#8217;t compile, we knew we would have to adapt Chrome to an interface change in the next roll patch.&#160;</li><li>If the bots were red, we knew we either had a bug in WebRTC or that Chrome would have to be adapted to some semantic change in WebRTC.</li></ul>The <a href="https://build.chromium.org/p/chromium.webrtc.fyi/waterfall">FYI &#8220;waterfall&#8221;</a> (a set of bots that builds and runs tests) is a straight copy of the <a href="https://build.chromium.org/p/chromium.webrtc/waterfall">main waterfall</a>, which is expensive in resources. We could have cheated and just set up FYI bots for one platform (say, Linux), but the most expensive regressions are platform-specific, so we reckoned the extra machines and maintenance were worth it.<br /><h2>Making Gradual Interface Changes&#160;</h2>This solution helped but wasn&#8217;t quite satisfactory. We initially had the policy that it was fine to break the FYI bots since we could not update Chrome to use a new interface until the new interface had actually been rolled into Chrome. This, however, often caused the FYI bots to be compile-broken for days. We quickly started to suffer from <a href="http://www.martinfowler.com/articles/continuousIntegration.html#FixBrokenBuildsImmediately">red blindness</a> <a href="http://googletesting.blogspot.com/#ref1">[1]</a> and had no idea if we would break tests on the roll, especially if an interface change was made early in the roll cycle. <br /><br />The solution was to move to a more careful update policy for the WebRTC API. For the more technically inclined, &#8220;careful&#8221; here means &#8220;following the <a href="https://wiki.eclipse.org/Evolving_Java-based_APIs#API_Prime_Directive">API prime directive</a>&#8221; <a href="http://googletesting.blogspot.com/#ref2">[2]</a>. Consider this example:<br /><pre><span>class</span> WebRtcAmplifier {<br />  ...<br /><span>int</span> SetOutputVolume(<span>float</span> volume);<br />}</pre><br />Normally we would just change the method&#8217;s signature when we needed to:<br /><pre><span>class</span> WebRtcAmplifier {<br />  ...<br /><span>int</span> SetOutputVolume(<span>float</span> volume, <span>bool</span> allow_eleven<a href="http://googletesting.blogspot.com/#foot1"><sup>1</sup></a>);<br />}</pre><br />&#8230; but this would compile-break Chome until it could be updated. So we started doing it like this instead:<br /><pre><span>class</span> WebRtcAmplifier {<br />  ...<br /><span>int</span> SetOutputVolume(<span>float</span> volume);<br /><span>int</span> SetOutputVolume2(<span>float</span> volume, <span>bool</span> allow_eleven);<br />}</pre><br />Then we could:<br /><ol><li>Roll into Chrome&#160;</li><li>Make Chrome use SetOutputVolume2&#160;</li><li>Update SetOutputVolume&#8217;s signature&#160;</li><li>Roll again and make Chrome use SetOutputVolume&#160;</li><li>Delete SetOutputVolume2</li></ol>This approach requires several steps but we end up with the right interface and at no point do we break Chrome.<br /><h2>Results</h2>When we implemented the above, we could fix problems as they came up rather than in big batches on each roll. We could institute the policy that the FYI bots should always be green, and that changes breaking them should be immediately rolled back. This made a huge difference. The team could work smoother and roll more often. This reduced our risk quite a bit, particularly when Chrome was about to cut a new version branch. Instead of doing panicked and risky rolls around a release, we could work out issues in good time and stay in control.<br /><br />Another benefit of FYI bots is more granular <a href="https://chromeperf.appspot.com/report?masters=ChromiumWebRTCFYI&#38;bots=chromium-webrtc-trunk-tot-rel-linux&#38;tests=browser_tests%2Fagc_energy_diff_with_agc&#38;checked=all">performance tests</a>. Before the FYI bots, it would frequently happen that a bunch of metrics regressed. However, it&#8217;s not fun to find which of the 100 patches in the roll caused the regression! With the FYI bots, we can see precisely which WebRTC revision caused the problem.<br /><h2>Future Work: Optimistic Auto-rolling</h2>The final step on this ladder (short of actually merging the repositories) is auto-rolling. The Blink team implemented this with their <a href="https://www.chromium.org/blink/blinkrollbot">ARB (AutoRollBot)</a>. The bot wakes up periodically and tries to do a roll patch. If it fails on the trybots, it waits and tries again later (perhaps the trybots failed because of a flake or other temporary error, or perhaps the error was real but has been fixed).<br /><br />To pull auto-rolling off, you are going to need very good tests. That goes for any roll patch (or any patch, really), but if you&#8217;re edging closer to a release and an unstoppable flood of code changes keep breaking you, you&#8217;re not in a good place.<br /><br /><hr /><h2>References</h2><a name="ref1"></a>[1] Martin Fowler (May 2006) &#8220;Continuous Integration&#8221;<br /><a name="ref2"></a>[2] Dani Megert, Remy Chi Jian Suen, et. al. (Oct 2014) &#8220;Evolving Java-based APIs&#8221;<br /><h2>Footnotes</h2><ol><li><a name="foot1"></a>We actually did have a hilarious bug in WebRTC where it was possible to set the volume to <a href="https://www.youtube.com/watch?v=KOO5S4vxi0o">1.1</a>, but only 0.0-1.0 was supposed to be allowed. No, really. Thus, our WebRTC implementation must be louder than the others since everybody knows 1.1 must be louder than 1.0.</li></ol><br />]]></description>
				<content:encoded><![CDATA[<i>Author: Patrik Höglund </i><br /><br />As we all know, software development is a complicated activity where we develop features and applications to provide value to our users. Furthermore, any nontrivial modern software is composed out of other software. For instance, the Chrome web browser pulls <a href="https://code.google.com/p/chromium/codesearch#chromium/src/third_party/&amp;sq=package:chromium">roughly a hundred libraries</a> into its third_party folder when you build the browser. The most significant of these libraries is Blink, the rendering engine, but there’s also ffmpeg for image processing, skia for low-level 2D graphics, and WebRTC for real-time communication (to name a few). <br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-6nJYH4SDvFc/VVZVadP56QI/AAAAAAAAAKQ/oEJRo9rro_s/s1600/image01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-6nJYH4SDvFc/VVZVadP56QI/AAAAAAAAAKQ/oEJRo9rro_s/s1600/image01.png" /></a></div><div style="text-align: center;"><i>Figure 1. Holy dependencies, Batman!</i></div><br />There are many reasons to use software libraries. Why write your own phone number parser when you can use <a href="https://github.com/googlei18n/libphonenumber">libphonenumber</a>, which is battle-tested by real use in Android and Chrome and available under a permissive license? Using such software frees you up to focus on the core of your software so you can deliver a unique experience to your users. On the other hand, you need to keep your application up to date with changes in the library (you want that latest bug fix, right?), and you also run a risk of such a change breaking your application. This article will examine that integration problem and how you can reduce the risks associated with it.<br /><h2>Updating Dependencies is Hard</h2>The simplest solution is to check in a copy of the library, build with it, and avoid touching it as much as possible. This solution, however, can be problematic because you miss out on bug fixes and new features in the library. What if you need a new feature or bug fix that just made it in? You have a few options:<br /><ul class="my-list"><li>Update the library to its latest release. If it’s been a long time since you did this, it can be quite risky and you may have to spend significant testing resources to ensure all the accumulated changes don’t break your application. You may have to catch up to interface changes in the library as well.&nbsp;</li><li>Cherry-pick the feature/bug fix you want into your copy of the library. This is even riskier because your cherry-picked patches may depend on other changes in the library in subtle ways. Also, you still are not up to date with the latest version.&nbsp;</li><li>Find some way to make do without the feature or bug fix.</li></ul>None of the above options are very good. Using this ad-hoc updating model can work if there’s a low volume of changes in the library and our requirements on the library don’t change very often. Even if that is the case, what will you do if a critical zero-day exploit is discovered in your socket library?  <br /><br />One way to mitigate the update risk is to integrate more often with your dependencies. As an extreme example, let’s look at Chrome. <br /><br />In Chrome development, there’s a massive amount of change going into its dependencies. The Blink rendering engine lives in a separate code repository from the browser. Blink sees hundreds of code changes per day, and Chrome must integrate with Blink often since it’s an important part of the browser. Another example is the WebRTC implementation, where a large part of Chrome’s implementation resides in the webrtc.org repository. This article will focus on the latter because it’s the team I happen to work on.<br /><h2>How “Rolling” Works&nbsp;</h2>The open-sourced WebRTC codebase is used by Chrome but also by a number of other companies working on WebRTC. Chrome uses a toolchain called depot_tools to manage dependencies, and there’s a checked-in text file called <a href="https://code.google.com/p/chromium/codesearch#chromium/src/DEPS&amp;q=DEPS&amp;sq=package:chromium&amp;l=1">DEPS</a> where dependencies are managed. It looks roughly like this:<br /><pre style="background: #f0f0f0; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;">{<br />  <span style="color: #4f8f00;"># ... </span><br />  <span style="color: #ff2600;">'src/third_party/webrtc'</span>:<br />      <span style="color: #ff2600;">'https://chromium.googlesource.com/'</span> +<br />      <span style="color: #ff2600;">'external/webrtc/trunk/webrtc.git'</span> + <br />      <span style="color: #ff2600;">'@'</span> + <span style="color: #ff2600;">'5727038f572c517204e1642b8bc69b25381c4e9f'</span>,<br />}<br /></pre><br />The above means we should pull WebRTC from the specified git repository at the <span style="font-family: Courier New, Courier, monospace;">572703...</span> hash, similar to other dependency-provisioning frameworks. To build Chrome with a new version, we change the hash and check in a new version of the <a href="https://code.google.com/p/chromium/codesearch#chromium/src/DEPS&amp;q=DEPS&amp;sq=package:chromium&amp;l=1">DEPS</a> file. If the library’s API has changed, we must update Chrome to use the new API in the same patch. This process is known as <i>rolling</i> WebRTC to a new version. <br /><br />Now the problem is that we have changed the code going into Chrome. Maybe <a href="https://code.google.com/p/chromium/issues/detail?id=430001">getUserMedia has started crashing on Android</a>, or maybe the browser no longer boots on Windows. We don’t know until we have built and run all the tests. Therefore a roll patch is subject to the same presubmit checks as any Chrome patch (i.e. <a href="https://www.chromium.org/developers/testing/try-server-usage">many tests, on all platforms we ship on</a>). However, roll patches can be considerably more painful and risky than other patches. <br /><br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-GWwsqyYm43c/VVZVf_WpvvI/AAAAAAAAAKY/qhlMLTB6nbA/s1600/image00.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-GWwsqyYm43c/VVZVf_WpvvI/AAAAAAAAAKY/qhlMLTB6nbA/s1600/image00.png" /></a></div><div style="text-align: center;"><i>Figure 2. Life of a Roll Patch.</i></div><br />On the WebRTC team we found ourselves in an uncomfortable position a couple years back. Developers would make changes to the webrtc.org code and there was a fair amount of churn in the interface, which meant we would have to update Chrome to adapt to those changes. Also we frequently broke tests and WebRTC functionality in Chrome because semantic changes had unexpected consequences in Chrome. Since rolls were so risky and painful to make, they started to happen less often, which made things even worse. There could be two weeks between rolls, which meant Chrome was hit by a large number of changes in one patch.<br /><h2>Bots That Can See the Future: “FYI Bots”&nbsp;</h2>We found a way to mitigate this which we called FYI (for your information) bots. A bot is Chrome lingo for a continuous build machine which builds Chrome and runs tests. <br /><br />All the existing Chrome bots at that point would build Chrome as specified in the <a href="https://code.google.com/p/chromium/codesearch#chromium/src/DEPS&amp;q=DEPS&amp;sq=package:chromium&amp;l=1">DEPS</a> file, which meant they would build the WebRTC version we had rolled to up to that point. FYI bots replace that pinned version with WebRTC HEAD, but otherwise build and run Chrome-level tests as usual. Therefore:  <br /><br /><ul class="my-list"><li>If all the FYI bots were green, we knew a roll most likely would go smoothly.&nbsp;</li><li>If the bots didn’t compile, we knew we would have to adapt Chrome to an interface change in the next roll patch.&nbsp;</li><li>If the bots were red, we knew we either had a bug in WebRTC or that Chrome would have to be adapted to some semantic change in WebRTC.</li></ul>The <a href="https://build.chromium.org/p/chromium.webrtc.fyi/waterfall">FYI “waterfall”</a> (a set of bots that builds and runs tests) is a straight copy of the <a href="https://build.chromium.org/p/chromium.webrtc/waterfall">main waterfall</a>, which is expensive in resources. We could have cheated and just set up FYI bots for one platform (say, Linux), but the most expensive regressions are platform-specific, so we reckoned the extra machines and maintenance were worth it.<br /><h2>Making Gradual Interface Changes&nbsp;</h2>This solution helped but wasn’t quite satisfactory. We initially had the policy that it was fine to break the FYI bots since we could not update Chrome to use a new interface until the new interface had actually been rolled into Chrome. This, however, often caused the FYI bots to be compile-broken for days. We quickly started to suffer from <a href="http://www.martinfowler.com/articles/continuousIntegration.html#FixBrokenBuildsImmediately">red blindness</a> <a href="http://googletesting.blogspot.com/2015/05/multi-repository-development.html#ref1">[1]</a> and had no idea if we would break tests on the roll, especially if an interface change was made early in the roll cycle. <br /><br />The solution was to move to a more careful update policy for the WebRTC API. For the more technically inclined, “careful” here means “following the <a href="https://wiki.eclipse.org/Evolving_Java-based_APIs#API_Prime_Directive">API prime directive</a>” <a href="http://googletesting.blogspot.com/2015/05/multi-repository-development.html#ref2">[2]</a>. Consider this example:<br /><pre style="background: #f0f0f0; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;"><span style="color: #0433ff;">class</span> WebRtcAmplifier {<br />  ...<br />  <span style="color: #0433ff;">int</span> SetOutputVolume(<span style="color: #0433ff;">float</span> volume);<br />}</pre><br />Normally we would just change the method’s signature when we needed to:<br /><pre style="background: #f0f0f0; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;"><span style="color: #0433ff;">class</span> WebRtcAmplifier {<br />  ...<br />  <span style="color: #0433ff;">int</span> SetOutputVolume(<span style="color: #0433ff;">float</span> volume, <span style="color: #0433ff;">bool</span> allow_eleven<a href="http://googletesting.blogspot.com/2015/05/multi-repository-development.html#foot1"><sup>1</sup></a>);<br />}</pre><br />… but this would compile-break Chome until it could be updated. So we started doing it like this instead:<br /><pre style="background: #f0f0f0; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;"><span style="color: #0433ff;">class</span> WebRtcAmplifier {<br />  ...<br />  <span style="color: #0433ff;">int</span> SetOutputVolume(<span style="color: #0433ff;">float</span> volume);<br />  <span style="color: #0433ff;">int</span> SetOutputVolume2(<span style="color: #0433ff;">float</span> volume, <span style="color: #0433ff;">bool</span> allow_eleven);<br />}</pre><br />Then we could:<br /><ol class="my-list"><li>Roll into Chrome&nbsp;</li><li>Make Chrome use SetOutputVolume2&nbsp;</li><li>Update SetOutputVolume’s signature&nbsp;</li><li>Roll again and make Chrome use SetOutputVolume&nbsp;</li><li>Delete SetOutputVolume2</li></ol>This approach requires several steps but we end up with the right interface and at no point do we break Chrome.<br /><h2>Results</h2>When we implemented the above, we could fix problems as they came up rather than in big batches on each roll. We could institute the policy that the FYI bots should always be green, and that changes breaking them should be immediately rolled back. This made a huge difference. The team could work smoother and roll more often. This reduced our risk quite a bit, particularly when Chrome was about to cut a new version branch. Instead of doing panicked and risky rolls around a release, we could work out issues in good time and stay in control.<br /><br />Another benefit of FYI bots is more granular <a href="https://chromeperf.appspot.com/report?masters=ChromiumWebRTCFYI&amp;bots=chromium-webrtc-trunk-tot-rel-linux&amp;tests=browser_tests%2Fagc_energy_diff_with_agc&amp;checked=all">performance tests</a>. Before the FYI bots, it would frequently happen that a bunch of metrics regressed. However, it’s not fun to find which of the 100 patches in the roll caused the regression! With the FYI bots, we can see precisely which WebRTC revision caused the problem.<br /><h2>Future Work: Optimistic Auto-rolling</h2>The final step on this ladder (short of actually merging the repositories) is auto-rolling. The Blink team implemented this with their <a href="https://www.chromium.org/blink/blinkrollbot">ARB (AutoRollBot)</a>. The bot wakes up periodically and tries to do a roll patch. If it fails on the trybots, it waits and tries again later (perhaps the trybots failed because of a flake or other temporary error, or perhaps the error was real but has been fixed).<br /><br />To pull auto-rolling off, you are going to need very good tests. That goes for any roll patch (or any patch, really), but if you’re edging closer to a release and an unstoppable flood of code changes keep breaking you, you’re not in a good place.<br /><br /><hr /><h2>References</h2><a name="ref1"></a>[1] Martin Fowler (May 2006) “Continuous Integration”<br /><a name="ref2"></a>[2] Dani Megert, Remy Chi Jian Suen, et. al. (Oct 2014) “Evolving Java-based APIs”<br /><h2>Footnotes</h2><ol class="my-list"><li><a name="foot1"></a>We actually did have a hilarious bug in WebRTC where it was possible to set the volume to <a href="https://www.youtube.com/watch?v=KOO5S4vxi0o">1.1</a>, but only 0.0-1.0 was supposed to be allowed. No, really. Thus, our WebRTC implementation must be louder than the others since everybody knows 1.1 must be louder than 1.0.</li></ol><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/multi-repository-development/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Just Say No to More End-to-End Tests</title>
		<link>https://googledata.org/google-testing/just-say-no-to-more-end-to-end-tests/</link>
		<comments>https://googledata.org/google-testing/just-say-no-to-more-end-to-end-tests/#comments</comments>
		<pubDate>Wed, 22 Apr 2015 22:49:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=6ae6cdc3db2683e65d2931252bd552cf</guid>
		<description><![CDATA[<i>by Mike Wacker </i><br /><br />At some point in your life, you can probably recall a movie that you and your friends all wanted to see, and that you and your friends all regretted watching afterwards. Or maybe you remember that time your team thought they&#8217;d found the next "killer feature" for their product, only to see that feature bomb after it was released. <br /><br />Good ideas often fail in practice, and in the world of testing, one pervasive good idea that often fails in practice is a testing strategy built around end-to-end tests. <br /><br />Testers can invest their time in writing many types of automated tests, including unit tests, integration tests, and end-to-end tests, but this strategy invests mostly in end-to-end tests that verify the product or service as a whole. Typically, these tests simulate real user scenarios.<br /><h2>End-to-End Tests in Theory&#160;</h2>While relying primarily on end-to-end tests is a bad idea, one could certainly convince a reasonable person that the idea makes sense in theory. <br /><br />To start, number one on Google's list of <a href="http://www.google.com/about/company/philosophy/">ten things we know to be true</a> is: "Focus on the user and all else will follow." Thus, end-to-end tests that focus on real user scenarios sound like a great idea. Additionally, this strategy broadly appeals to many constituencies:<br /><ul><li><b>Developers</b> like it because it offloads most, if not all, of the testing to others.&#160;</li><li><b>Managers and decision-makers</b> like it because tests that simulate real user scenarios can help them easily determine how a failing test would impact the user.&#160;</li><li><b>Testers</b> like it because they often worry about missing a bug or writing a test that does not verify real-world behavior; writing tests from the user's perspective often avoids both problems and gives the tester a greater sense of accomplishment.&#160;</li></ul><h2>End-to-End Tests in Practice&#160;</h2>So if this testing strategy sounds so good in theory, then where does it go wrong in practice? To demonstrate, I present the following composite sketch based on a collection of real experiences familiar to both myself and other testers. In this sketch, a team is building a service for editing documents online (e.g., Google Docs). <br /><br />Let's assume the team already has some fantastic test infrastructure in place. Every night:<br /><ol><li>The latest version of the service is built.&#160;</li><li>This version is then deployed to the team's testing environment.&#160;</li><li>All end-to-end tests then run against this testing environment.&#160;</li><li>An email report summarizing the test results is sent to the team.</li></ol><br />The deadline is approaching fast as our team codes new features for their next release. To maintain a high bar for product quality, they also require that at least 90% of their end-to-end tests pass before features are considered complete. Currently, that deadline is one day away:  <br /><br /><table><tbody><tr><td>Days Left</td><td>Pass %</td><td>Notes</td></tr><tr><td>1</td><td>5%</td><td>Everything is broken! Signing in to the service is broken. Almost all tests sign in a user, so almost all tests failed.</td></tr><tr><td>0</td><td>4%</td><td>A partner team we rely on deployed a bad build to their testing environment yesterday.</td></tr><tr><td>-1</td><td>54%</td><td>A dev broke the save scenario yesterday (or the day before?). Half the tests save a document at some point in time. Devs spent most of the day determining if it's a frontend bug or a backend bug.</td></tr><tr><td>-2</td><td>54%</td><td>It's a frontend bug, devs spent half of today figuring out where.</td></tr><tr><td>-3</td><td>54%</td><td>A bad fix was checked in yesterday. The mistake was pretty easy to spot, though, and a correct fix was checked in today.</td></tr><tr><td>-4</td><td>1%</td><td>Hardware failures occurred in the lab for our testing environment.</td></tr><tr><td>-5</td><td>84%</td><td>Many small bugs hiding behind the big bugs (e.g., sign-in broken, save broken). Still working on the small bugs.</td></tr><tr><td>-6</td><td>87%</td><td>We should be above 90%, but are not for some reason.</td></tr><tr><td>-7</td><td>89.54%</td><td>(Rounds up to 90%, close enough.) No fixes were checked in yesterday, so the tests must have been flaky yesterday.</td></tr></tbody></table><br /><h3>Analysis&#160;</h3>Despite numerous problems, the tests ultimately did catch real bugs.<br /><br /><h4>What Went Well&#160;</h4><ul><li>Customer-impacting bugs were identified and fixed before they reached the customer.</li></ul><br /><h4>What Went Wrong&#160;</h4><ul><li>The team completed their coding milestone a week late (and worked a lot of overtime).&#160;</li><li>Finding the root cause for a failing end-to-end test is painful and can take a long time.&#160;</li><li>Partner failures and lab failures ruined the test results on multiple days.&#160;</li><li>Many smaller bugs were hidden behind bigger bugs.&#160;</li><li>End-to-end tests were flaky at times.&#160;</li><li>Developers had to wait until the following day to know if a fix worked or not.&#160;</li></ul><br />So now that we know what went wrong with the end-to-end strategy, we need to change our approach to testing to avoid many of these problems. But what is the right approach?<br /><h2>The True Value of Tests&#160;</h2>Typically, a tester's job ends once they have a failing test. A bug is filed, and then it's the developer's job to fix the bug. To identify where the end-to-end strategy breaks down, however, we need to think outside this box and approach the problem from first principles. If we "focus on the user (and all else will follow)," we have to ask ourselves how a failing test benefits the user. Here is the answer:<br /><br /><b>A failing test does not directly benefit the user.&#160;</b><br /><br />While this statement seems shocking at first, it is true. If a product works, it works, whether a test says it works or not. If a product is broken, it is broken, whether a test says it is broken or not. So, if failing tests do not benefit the user, then what does benefit the user?<br /><br /><b>A bug fix directly benefits the user.</b><br /><br />The user will only be happy when that unintended behavior - the bug - goes away. Obviously, to fix a bug, you must know the bug exists. To know the bug exists, ideally you have a test that catches the bug (because the user will find the bug if the test does not). But in that entire process, from failing test to bug fix, value is only added at the very last step.  <br /><br /><table><tbody><tr><td>Stage</td><td>Failing Test</td><td>Bug Opened</td><td>Bug Fixed</td></tr><tr><td>Value Added</td><td>No</td><td>No</td><td>Yes</td></tr></tbody></table><br />Thus, to evaluate any testing strategy, you cannot just evaluate how it finds bugs. You also must evaluate how it enables developers to fix (and even prevent) bugs.<br /><h2>Building the Right Feedback Loop</h2>Tests create a feedback loop that informs the developer whether the product is working or not. The ideal feedback loop has several properties:<br /><ul><li><b>It's fast</b>. No developer wants to wait hours or days to find out if their change works. Sometimes the change does not work - nobody is perfect - and the feedback loop needs to run multiple times. A faster feedback loop leads to faster fixes. If the loop is fast enough, developers may even run tests before checking in a change.&#160;</li><li><b>It's reliable</b>. No developer wants to spend hours debugging a test, only to find out it was a flaky test. Flaky tests reduce the developer's trust in the test, and as a result flaky tests are often ignored, even when they find real product issues.&#160;</li><li><b>It isolates failures</b>. To fix a bug, developers need to find the specific lines of code causing the bug. When a product contains millions of lines of codes, and the bug could be anywhere, it's like trying to find a needle in a haystack.&#160;</li></ul><h2>Think Smaller, Not Larger</h2>So how do we create that ideal feedback loop? By thinking smaller, not larger.<br /><br /><h3>Unit Tests</h3>Unit tests take a small piece of the product and test that piece in isolation. They tend to create that ideal feedback loop:<br /><br /><ul><li><b>Unit tests are fast</b>. We only need to build a small unit to test it, and the tests also tend to be rather small. In fact, one tenth of a second is considered slow for unit tests.&#160;</li><li><b>Unit tests are reliable</b>. Simple systems and small units in general tend to suffer much less from flakiness. Furthermore, best practices for unit testing - in particular practices related to hermetic tests - will remove flakiness entirely.&#160;</li><li><b>Unit tests isolate failures</b>. Even if a product contains millions of lines of code, if a unit test fails, you only need to search that small unit under test to find the bug.&#160;</li></ul><br />Writing effective unit tests requires skills in areas such as dependency management, mocking, and hermetic testing. I won't cover these skills here, but as a start, the typical example offered to new Googlers (or Nooglers) is how Google <a href="https://github.com/google/guava/blob/master/guava/src/com/google/common/base/Stopwatch.java">builds</a> and <a href="https://github.com/google/guava/blob/master/guava-tests/test/com/google/common/base/StopwatchTest.java">tests</a> a stopwatch.<br /><br /><h3>Unit Tests vs. End-to-End Tests</h3>With end-to-end tests, you have to wait: first for the entire product to be built, then for it to be deployed, and finally for all end-to-end tests to run. When the tests do run, flaky tests tend to be a fact of life. And even if a test finds a bug, that bug could be anywhere in the product.<br /><br />Although end-to-end tests do a better job of simulating real user scenarios, this advantage quickly becomes outweighed by all the disadvantages of the end-to-end feedback loop:  <br /><br /><table><tbody><tr><td></td><td>Unit</td><td>End-toEnd</td></tr><tr><td>Fast</td><td><div><a href="http://2.bp.blogspot.com/-Fp_uRzlgj_g/VTgeI4I5B2I/AAAAAAAAAJs/MyLzM2aMqoc/s1600/happy.png"><img border="0" src="http://2.bp.blogspot.com/-Fp_uRzlgj_g/VTgeI4I5B2I/AAAAAAAAAJs/MyLzM2aMqoc/s1600/happy.png"></a></div><br /></td><td><div><a href="http://4.bp.blogspot.com/-iWLqXFZLJZs/VTgeM4TVclI/AAAAAAAAAJ0/OLSRuxk_KRY/s1600/sad.png"><img border="0" src="http://4.bp.blogspot.com/-iWLqXFZLJZs/VTgeM4TVclI/AAAAAAAAAJ0/OLSRuxk_KRY/s1600/sad.png"></a></div><br /></td></tr><tr><td>Reliable</td><td><div><a href="http://2.bp.blogspot.com/-Fp_uRzlgj_g/VTgeI4I5B2I/AAAAAAAAAJs/MyLzM2aMqoc/s1600/happy.png"><img border="0" src="http://2.bp.blogspot.com/-Fp_uRzlgj_g/VTgeI4I5B2I/AAAAAAAAAJs/MyLzM2aMqoc/s1600/happy.png"></a></div><br /></td><td><div><a href="http://4.bp.blogspot.com/-iWLqXFZLJZs/VTgeM4TVclI/AAAAAAAAAJ0/OLSRuxk_KRY/s1600/sad.png"><img border="0" src="http://4.bp.blogspot.com/-iWLqXFZLJZs/VTgeM4TVclI/AAAAAAAAAJ0/OLSRuxk_KRY/s1600/sad.png"></a></div><div><br /></div><br /></td></tr><tr><td>Isolates Failures</td><td><div><a href="http://2.bp.blogspot.com/-Fp_uRzlgj_g/VTgeI4I5B2I/AAAAAAAAAJs/MyLzM2aMqoc/s1600/happy.png"><img border="0" src="http://2.bp.blogspot.com/-Fp_uRzlgj_g/VTgeI4I5B2I/AAAAAAAAAJs/MyLzM2aMqoc/s1600/happy.png"></a></div><br /></td><td><div><a href="http://4.bp.blogspot.com/-iWLqXFZLJZs/VTgeM4TVclI/AAAAAAAAAJ0/OLSRuxk_KRY/s1600/sad.png"><img border="0" src="http://4.bp.blogspot.com/-iWLqXFZLJZs/VTgeM4TVclI/AAAAAAAAAJ0/OLSRuxk_KRY/s1600/sad.png"></a></div><br /></td></tr><tr><td>Simulates a Real User</td><td><div><a href="http://4.bp.blogspot.com/-iWLqXFZLJZs/VTgeM4TVclI/AAAAAAAAAJ0/OLSRuxk_KRY/s1600/sad.png"><img border="0" src="http://4.bp.blogspot.com/-iWLqXFZLJZs/VTgeM4TVclI/AAAAAAAAAJ0/OLSRuxk_KRY/s1600/sad.png"></a></div><br /></td><td><div><a href="http://2.bp.blogspot.com/-Fp_uRzlgj_g/VTgeI4I5B2I/AAAAAAAAAJs/MyLzM2aMqoc/s1600/happy.png"><img border="0" src="http://2.bp.blogspot.com/-Fp_uRzlgj_g/VTgeI4I5B2I/AAAAAAAAAJs/MyLzM2aMqoc/s1600/happy.png"></a></div><br /></td></tr></tbody></table><br /><h3>Integration Tests</h3>Unit tests do have one major disadvantage: even if the units work well in isolation, you do not know if they work well together. But even then, you do not necessarily need end-to-end tests. For that, you can use an integration test. An integration test takes a small group of units, often two units, and tests their behavior as a whole, verifying that they coherently work together.<br /><br />If two units do not integrate properly, why write an end-to-end test when you can write a much smaller, more focused integration test that will detect the same bug? While you do need to think larger, you only need to think a little larger to verify that units work together.<br /><h2>Testing Pyramid</h2>Even with both unit tests and integration tests, you probably still will want a small number of end-to-end tests to verify the system as a whole. To find the right balance between all three test types, the best visual aid to use is the testing pyramid. Here is a simplified version of the <a href="https://docs.google.com/presentation/d/15gNk21rjer3xo-b1ZqyQVGebOp_aPvHU3YH7YnOMxtE/edit#slide=id.g437663ce1_53_98">testing pyramid</a> from the opening keynote of the <a href="https://developers.google.com/google-test-automation-conference/2014/">2014 Google Test Automation Conference</a>:  <br /><br /><div><a href="http://2.bp.blogspot.com/-YTzv_O4TnkA/VTgexlumP1I/AAAAAAAAAJ8/57-rnwyvP6g/s1600/image02.png"><img border="0" src="http://2.bp.blogspot.com/-YTzv_O4TnkA/VTgexlumP1I/AAAAAAAAAJ8/57-rnwyvP6g/s1600/image02.png" height="276" width="320"></a></div><br /><br />The bulk of your tests are unit tests at the bottom of the pyramid. As you move up the pyramid, your tests gets larger, but at the same time the number of tests (the width of your pyramid) gets smaller.<br /><br />As a good first guess, Google often suggests a 70/20/10 split: 70% unit tests, 20% integration tests, and 10% end-to-end tests. The exact mix will be different for each team, but in general, it should retain that pyramid shape. Try to avoid these anti-patterns:<br /><ul><li><b>Inverted pyramid/ice cream cone</b>. The team relies primarily on end-to-end tests, using few integration tests and even fewer unit tests.&#160;</li><li><b>Hourglass</b>. The team starts with a lot of unit tests, then uses end-to-end tests where integration tests should be used. The hourglass has many unit tests at the bottom and many end-to-end tests at the top, but few integration tests in the middle.&#160;</li></ul>Just like a regular pyramid tends to be the most stable structure in real life, the testing pyramid also tends to be the most stable testing strategy. <br /><br /><br />]]></description>
				<content:encoded><![CDATA[<i>by Mike Wacker </i><br /><br />At some point in your life, you can probably recall a movie that you and your friends all wanted to see, and that you and your friends all regretted watching afterwards. Or maybe you remember that time your team thought they’d found the next "killer feature" for their product, only to see that feature bomb after it was released. <br /><br />Good ideas often fail in practice, and in the world of testing, one pervasive good idea that often fails in practice is a testing strategy built around end-to-end tests. <br /><br />Testers can invest their time in writing many types of automated tests, including unit tests, integration tests, and end-to-end tests, but this strategy invests mostly in end-to-end tests that verify the product or service as a whole. Typically, these tests simulate real user scenarios.<br /><h2>End-to-End Tests in Theory&nbsp;</h2>While relying primarily on end-to-end tests is a bad idea, one could certainly convince a reasonable person that the idea makes sense in theory. <br /><br />To start, number one on Google's list of <a href="http://www.google.com/about/company/philosophy/">ten things we know to be true</a> is: "Focus on the user and all else will follow." Thus, end-to-end tests that focus on real user scenarios sound like a great idea. Additionally, this strategy broadly appeals to many constituencies:<br /><ul class="my-list"><li><b>Developers</b> like it because it offloads most, if not all, of the testing to others.&nbsp;</li><li><b>Managers and decision-makers</b> like it because tests that simulate real user scenarios can help them easily determine how a failing test would impact the user.&nbsp;</li><li><b>Testers</b> like it because they often worry about missing a bug or writing a test that does not verify real-world behavior; writing tests from the user's perspective often avoids both problems and gives the tester a greater sense of accomplishment.&nbsp;</li></ul><h2>End-to-End Tests in Practice&nbsp;</h2>So if this testing strategy sounds so good in theory, then where does it go wrong in practice? To demonstrate, I present the following composite sketch based on a collection of real experiences familiar to both myself and other testers. In this sketch, a team is building a service for editing documents online (e.g., Google Docs). <br /><br />Let's assume the team already has some fantastic test infrastructure in place. Every night:<br /><ol class="my-list"><li>The latest version of the service is built.&nbsp;</li><li>This version is then deployed to the team's testing environment.&nbsp;</li><li>All end-to-end tests then run against this testing environment.&nbsp;</li><li>An email report summarizing the test results is sent to the team.</li></ol><br />The deadline is approaching fast as our team codes new features for their next release. To maintain a high bar for product quality, they also require that at least 90% of their end-to-end tests pass before features are considered complete. Currently, that deadline is one day away:  <br /><br /><table class="my-bordered-table" style="color: black;"><tbody><tr><td style="white-space: nowrap;">Days Left</td><td>Pass %</td><td>Notes</td></tr><tr style="background-color: red;"><td>1</td><td>5%</td><td>Everything is broken! Signing in to the service is broken. Almost all tests sign in a user, so almost all tests failed.</td></tr><tr style="background-color: red;"><td>0</td><td>4%</td><td>A partner team we rely on deployed a bad build to their testing environment yesterday.</td></tr><tr style="background-color: orange;"><td>-1</td><td>54%</td><td>A dev broke the save scenario yesterday (or the day before?). Half the tests save a document at some point in time. Devs spent most of the day determining if it's a frontend bug or a backend bug.</td></tr><tr style="background-color: orange;"><td>-2</td><td>54%</td><td>It's a frontend bug, devs spent half of today figuring out where.</td></tr><tr style="background-color: orange;"><td>-3</td><td>54%</td><td>A bad fix was checked in yesterday. The mistake was pretty easy to spot, though, and a correct fix was checked in today.</td></tr><tr style="background-color: red;"><td>-4</td><td>1%</td><td>Hardware failures occurred in the lab for our testing environment.</td></tr><tr style="background-color: yellow;"><td>-5</td><td>84%</td><td>Many small bugs hiding behind the big bugs (e.g., sign-in broken, save broken). Still working on the small bugs.</td></tr><tr style="background-color: yellow;"><td>-6</td><td>87%</td><td>We should be above 90%, but are not for some reason.</td></tr><tr style="background-color: lime;"><td>-7</td><td>89.54%</td><td>(Rounds up to 90%, close enough.) No fixes were checked in yesterday, so the tests must have been flaky yesterday.</td></tr></tbody></table><br /><h3>Analysis&nbsp;</h3>Despite numerous problems, the tests ultimately did catch real bugs.<br /><br /><h4>What Went Well&nbsp;</h4><ul class="my-list"><li>Customer-impacting bugs were identified and fixed before they reached the customer.</li></ul><br /><h4>What Went Wrong&nbsp;</h4><ul class="my-list"><li>The team completed their coding milestone a week late (and worked a lot of overtime).&nbsp;</li><li>Finding the root cause for a failing end-to-end test is painful and can take a long time.&nbsp;</li><li>Partner failures and lab failures ruined the test results on multiple days.&nbsp;</li><li>Many smaller bugs were hidden behind bigger bugs.&nbsp;</li><li>End-to-end tests were flaky at times.&nbsp;</li><li>Developers had to wait until the following day to know if a fix worked or not.&nbsp;</li></ul><br />So now that we know what went wrong with the end-to-end strategy, we need to change our approach to testing to avoid many of these problems. But what is the right approach?<br /><h2>The True Value of Tests&nbsp;</h2>Typically, a tester's job ends once they have a failing test. A bug is filed, and then it's the developer's job to fix the bug. To identify where the end-to-end strategy breaks down, however, we need to think outside this box and approach the problem from first principles. If we "focus on the user (and all else will follow)," we have to ask ourselves how a failing test benefits the user. Here is the answer:<br /><br /><b>A failing test does not directly benefit the user.&nbsp;</b><br /><br />While this statement seems shocking at first, it is true. If a product works, it works, whether a test says it works or not. If a product is broken, it is broken, whether a test says it is broken or not. So, if failing tests do not benefit the user, then what does benefit the user?<br /><br /><b>A bug fix directly benefits the user.</b><br /><br />The user will only be happy when that unintended behavior - the bug - goes away. Obviously, to fix a bug, you must know the bug exists. To know the bug exists, ideally you have a test that catches the bug (because the user will find the bug if the test does not). But in that entire process, from failing test to bug fix, value is only added at the very last step.  <br /><br /><table class="my-bordered-table" style="color: black; text-align: left;"><tbody><tr><td>Stage</td><td style="background-color: red;">Failing Test</td><td style="background-color: red;">Bug Opened</td><td style="background-color: lime;">Bug Fixed</td></tr><tr><td>Value Added</td><td style="background-color: red;">No</td><td style="background-color: red;">No</td><td style="background-color: lime;">Yes</td></tr></tbody></table><br />Thus, to evaluate any testing strategy, you cannot just evaluate how it finds bugs. You also must evaluate how it enables developers to fix (and even prevent) bugs.<br /><h2>Building the Right Feedback Loop</h2>Tests create a feedback loop that informs the developer whether the product is working or not. The ideal feedback loop has several properties:<br /><ul class="my-list"><li><b>It's fast</b>. No developer wants to wait hours or days to find out if their change works. Sometimes the change does not work - nobody is perfect - and the feedback loop needs to run multiple times. A faster feedback loop leads to faster fixes. If the loop is fast enough, developers may even run tests before checking in a change.&nbsp;</li><li><b>It's reliable</b>. No developer wants to spend hours debugging a test, only to find out it was a flaky test. Flaky tests reduce the developer's trust in the test, and as a result flaky tests are often ignored, even when they find real product issues.&nbsp;</li><li><b>It isolates failures</b>. To fix a bug, developers need to find the specific lines of code causing the bug. When a product contains millions of lines of codes, and the bug could be anywhere, it's like trying to find a needle in a haystack.&nbsp;</li></ul><h2>Think Smaller, Not Larger</h2>So how do we create that ideal feedback loop? By thinking smaller, not larger.<br /><br /><h3>Unit Tests</h3>Unit tests take a small piece of the product and test that piece in isolation. They tend to create that ideal feedback loop:<br /><br /><ul class="my-list"><li><b>Unit tests are fast</b>. We only need to build a small unit to test it, and the tests also tend to be rather small. In fact, one tenth of a second is considered slow for unit tests.&nbsp;</li><li><b>Unit tests are reliable</b>. Simple systems and small units in general tend to suffer much less from flakiness. Furthermore, best practices for unit testing - in particular practices related to hermetic tests - will remove flakiness entirely.&nbsp;</li><li><b>Unit tests isolate failures</b>. Even if a product contains millions of lines of code, if a unit test fails, you only need to search that small unit under test to find the bug.&nbsp;</li></ul><br />Writing effective unit tests requires skills in areas such as dependency management, mocking, and hermetic testing. I won't cover these skills here, but as a start, the typical example offered to new Googlers (or Nooglers) is how Google <a href="https://github.com/google/guava/blob/master/guava/src/com/google/common/base/Stopwatch.java">builds</a> and <a href="https://github.com/google/guava/blob/master/guava-tests/test/com/google/common/base/StopwatchTest.java">tests</a> a stopwatch.<br /><br /><h3>Unit Tests vs. End-to-End Tests</h3>With end-to-end tests, you have to wait: first for the entire product to be built, then for it to be deployed, and finally for all end-to-end tests to run. When the tests do run, flaky tests tend to be a fact of life. And even if a test finds a bug, that bug could be anywhere in the product.<br /><br />Although end-to-end tests do a better job of simulating real user scenarios, this advantage quickly becomes outweighed by all the disadvantages of the end-to-end feedback loop:  <br /><br /><table class="my-bordered-table" style="color: black;"><tbody><tr><td></td><td>Unit</td><td>End-toEnd</td></tr><tr><td>Fast</td><td><div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-Fp_uRzlgj_g/VTgeI4I5B2I/AAAAAAAAAJs/MyLzM2aMqoc/s1600/happy.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-Fp_uRzlgj_g/VTgeI4I5B2I/AAAAAAAAAJs/MyLzM2aMqoc/s1600/happy.png" /></a></div><br /></td><td><div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-iWLqXFZLJZs/VTgeM4TVclI/AAAAAAAAAJ0/OLSRuxk_KRY/s1600/sad.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-iWLqXFZLJZs/VTgeM4TVclI/AAAAAAAAAJ0/OLSRuxk_KRY/s1600/sad.png" /></a></div><br /></td></tr><tr><td>Reliable</td><td><div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-Fp_uRzlgj_g/VTgeI4I5B2I/AAAAAAAAAJs/MyLzM2aMqoc/s1600/happy.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-Fp_uRzlgj_g/VTgeI4I5B2I/AAAAAAAAAJs/MyLzM2aMqoc/s1600/happy.png" /></a></div><br /></td><td><div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-iWLqXFZLJZs/VTgeM4TVclI/AAAAAAAAAJ0/OLSRuxk_KRY/s1600/sad.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-iWLqXFZLJZs/VTgeM4TVclI/AAAAAAAAAJ0/OLSRuxk_KRY/s1600/sad.png" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><br /></td></tr><tr><td>Isolates Failures</td><td><div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-Fp_uRzlgj_g/VTgeI4I5B2I/AAAAAAAAAJs/MyLzM2aMqoc/s1600/happy.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-Fp_uRzlgj_g/VTgeI4I5B2I/AAAAAAAAAJs/MyLzM2aMqoc/s1600/happy.png" /></a></div><br /></td><td><div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-iWLqXFZLJZs/VTgeM4TVclI/AAAAAAAAAJ0/OLSRuxk_KRY/s1600/sad.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-iWLqXFZLJZs/VTgeM4TVclI/AAAAAAAAAJ0/OLSRuxk_KRY/s1600/sad.png" /></a></div><br /></td></tr><tr><td>Simulates a Real User</td><td><div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-iWLqXFZLJZs/VTgeM4TVclI/AAAAAAAAAJ0/OLSRuxk_KRY/s1600/sad.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-iWLqXFZLJZs/VTgeM4TVclI/AAAAAAAAAJ0/OLSRuxk_KRY/s1600/sad.png" /></a></div><br /></td><td><div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-Fp_uRzlgj_g/VTgeI4I5B2I/AAAAAAAAAJs/MyLzM2aMqoc/s1600/happy.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-Fp_uRzlgj_g/VTgeI4I5B2I/AAAAAAAAAJs/MyLzM2aMqoc/s1600/happy.png" /></a></div><br /></td></tr></tbody></table><br /><h3>Integration Tests</h3>Unit tests do have one major disadvantage: even if the units work well in isolation, you do not know if they work well together. But even then, you do not necessarily need end-to-end tests. For that, you can use an integration test. An integration test takes a small group of units, often two units, and tests their behavior as a whole, verifying that they coherently work together.<br /><br />If two units do not integrate properly, why write an end-to-end test when you can write a much smaller, more focused integration test that will detect the same bug? While you do need to think larger, you only need to think a little larger to verify that units work together.<br /><h2>Testing Pyramid</h2>Even with both unit tests and integration tests, you probably still will want a small number of end-to-end tests to verify the system as a whole. To find the right balance between all three test types, the best visual aid to use is the testing pyramid. Here is a simplified version of the <a href="https://docs.google.com/presentation/d/15gNk21rjer3xo-b1ZqyQVGebOp_aPvHU3YH7YnOMxtE/edit#slide=id.g437663ce1_53_98">testing pyramid</a> from the opening keynote of the <a href="https://developers.google.com/google-test-automation-conference/2014/">2014 Google Test Automation Conference</a>:  <br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-YTzv_O4TnkA/VTgexlumP1I/AAAAAAAAAJ8/57-rnwyvP6g/s1600/image02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-YTzv_O4TnkA/VTgexlumP1I/AAAAAAAAAJ8/57-rnwyvP6g/s1600/image02.png" height="276" width="320" /></a></div><br /><br />The bulk of your tests are unit tests at the bottom of the pyramid. As you move up the pyramid, your tests gets larger, but at the same time the number of tests (the width of your pyramid) gets smaller.<br /><br />As a good first guess, Google often suggests a 70/20/10 split: 70% unit tests, 20% integration tests, and 10% end-to-end tests. The exact mix will be different for each team, but in general, it should retain that pyramid shape. Try to avoid these anti-patterns:<br /><ul class="my-list"><li><b>Inverted pyramid/ice cream cone</b>. The team relies primarily on end-to-end tests, using few integration tests and even fewer unit tests.&nbsp;</li><li><b>Hourglass</b>. The team starts with a lot of unit tests, then uses end-to-end tests where integration tests should be used. The hourglass has many unit tests at the bottom and many end-to-end tests at the top, but few integration tests in the middle.&nbsp;</li></ul>Just like a regular pyramid tends to be the most stable structure in real life, the testing pyramid also tends to be the most stable testing strategy. <br /><br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/just-say-no-to-more-end-to-end-tests/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Quantum Quality</title>
		<link>https://googledata.org/google-testing/quantum-quality/</link>
		<comments>https://googledata.org/google-testing/quantum-quality/#comments</comments>
		<pubDate>Wed, 01 Apr 2015 09:30:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=eb3ec7363b4d897e03762e4693f57dac</guid>
		<description><![CDATA[UPDATE:&#160;Hey, this was an April fool's joke but in fact we wished we couldhave realized this idea and we are looking forward to the day this hasbeen worked out and becomes a reality.by Kevin Graney Here at Google we have a long history of capitaliz...]]></description>
				<content:encoded><![CDATA[<div style="text-align: center;"><span style="color: red;">UPDATE</span>:&nbsp;Hey, this was an April fool's joke but in fact we wished we could</div><div style="text-align: center;">have realized this idea and we are looking forward to the day this has</div><div style="text-align: center;">been worked out and becomes a reality.</div><i><br /></i><i>by Kevin Graney </i><br /><br />Here at Google we have a long history of capitalizing on the latest research and technology to improve the quality of our software.  Over our past 16+ years as a company, what started with some humble unit tests has grown into a massive operation.  As our software complexity increased, ever larger and more complex tests were dreamed up by our Software Engineers in Test (SETs). <br /><br />What we have come to realize is that our love of testing is a double-edged sword.  On the one hand, large-scale testing keeps us honest and gives us confidence.  It ensures our products remain reliable, our users' data is kept safe, and our engineers are able to work productively without fear of breaking things.  On the other hand, it's expensive in both engineer and machine time.  Our SETs have been working tirelessly to reduce the expense and latency of software tests at Google, while continuing to increase their quality. <br /><br />Today, we're excited to reveal how Google is tackling this challenge.  In collaboration with the <a href="https://plus.google.com/+QuantumAILab">Quantum AI Lab</a>, SETs at Google have been busy revolutionizing how software is tested.  The theory is relatively simple: bits in a traditional computer are either zero or one, but bits in a quantum computer can be both one and zero at the same time.  This is known as superposition, and the classic example is <a href="http://en.wikipedia.org/wiki/Schr%C3%B6dinger%27s_cat">Schrodinger's cat</a>.  Through some clever math and cutting edge electrical engineering, researchers at Google have figured out how to utilize superposition to vastly improve the quality of our software testing and the speed at which our tests run. <br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-3Z-mBr4H0E4/VRoJwyCq0cI/AAAAAAAAAJI/lrWTbEvy4cc/s1600/image04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-3Z-mBr4H0E4/VRoJwyCq0cI/AAAAAAAAAJI/lrWTbEvy4cc/s1600/image04.png" height="316" width="400" /></a></div><br /><div style="text-align: center;"><b>Figure 1</b> Some qubits inside a Google quantum device. </div><br />With superposition, tests at Google are now able to simultaneously model every possible state of the application under test.  The state of the application can be thought of as an <i>n</i> bit sequential memory buffer, consistent with the traditional <a href="http://en.wikipedia.org/wiki/Von_Neumann_architecture">Von Neuman architecture</a> of computing.  Because each bit under superposition is simultaneously a 0 and a 1, these tests can simulate 2<span style="font-size: small; vertical-align: super;"><i>n</i></span> different application states at any given instant in time in <i>O(n)</i> space.  Each of these application states can be mutated by application logic to another state in constant time using quantum algorithms developed by Google researchers.  These two properties together allow us to build a state transition graph of the application under test that shows every possible application state and all possible transitions to other application states.  Using traditional computing methods this problem has intractable time complexity, but after leveraging superposition and our quantum algorithms it becomes relatively fast and cheap. <br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-gLI5SNZjBig/VRoKv62JrNI/AAAAAAAAAJY/CdmF33KtFjo/s1600/state.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-gLI5SNZjBig/VRoKv62JrNI/AAAAAAAAAJY/CdmF33KtFjo/s1600/state.png" /></a></div><div style="margin-left: auto; margin-right: auto; width: 500px;"><b>Figure 2</b> The application state graph for a demonstrative 3-bit application.  If the start state is 001 then 000, 110, 111, and 011 are all unreachable states.  States 010 and 100 both result in deadlock. </div><br /><div style="text-align: justify;">Once we have the state transition graph for the application under test, testing it becomes almost trivial.  Given the initial startup state of the application, i.e. the executable bits of the application stored on disk, we can find from the application's state transition graph all reachable states.  Assertions that ensure proper behavior are then written against the reachable subset of the transition graph.  This paradigm of test writing allows both Google's security engineers and software engineers to work more productively.  A security engineer can write a test, for example, that asserts "no executable memory regions become mutated in any reachable state".  This one test effectively eliminates the potential for security flaws that result from <a href="http://en.wikipedia.org/wiki/Memory_safety">memory safety violations</a>.  A test engineer can write higher level assertions using graph traversal methods that ensure data integrity is maintained across a subset of application state transitions.  Tests of this nature can detect data corruption bugs. </div><br />We're excited about the work our team has done so far to push the envelope in the field of quantum software quality.  We're just getting started, but based on early dogfood results among Googlers we believe the potential of this work is huge.  Stay tuned! <br /><br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/quantum-quality/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Android UI Automated Testing</title>
		<link>https://googledata.org/google-testing/android-ui-automated-testing/</link>
		<comments>https://googledata.org/google-testing/android-ui-automated-testing/#comments</comments>
		<pubDate>Fri, 20 Mar 2015 20:49:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>
		<category><![CDATA[mobile]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=f22535e0050b3c0f1009e65f441c3016</guid>
		<description><![CDATA[<i>by Mona El Mahdy </i><br /><br /><span><b>Overview </b></span><br /><br />This post reviews four strategies for Android UI testing with the goal of creating UI tests that are fast, reliable, and easy to debug.<br /><br />Before we begin, let&#8217;s not forget an important rule: whatever can be unit tested should be unit tested. <a href="http://robolectric.org/">Robolectric</a> and <a href="http://tools.android.com/tech-docs/unit-testing-support">gradle unit tests support</a> are great examples of unit test frameworks for Android. UI tests, on the other hand, are used to verify that your application returns the correct UI output in response to a sequence of user actions on a device. <a href="http://developer.android.com/tools/testing-support-library/index.html#Espresso">Espresso</a> is a great framework for running UI actions and verifications in the same process. For more details on the Espresso and UI Automator tools, please see: <a href="http://developer.android.com/tools/testing-support-library/index.html">test support libraries</a>. <br /><br />The Google+ team has performed many iterations of UI testing. Below we discuss the lessons learned during each strategy of UI testing. Stay tuned for more posts with more details and code samples. <br /><br /><span><b>Strategy 1: Using an End-To-End Test as a UI Test </b></span><br /><br />Let&#8217;s start with some definitions. A <b>UI test</b> ensures that your application returns the correct UI output in response to a sequence of user actions on a device. An <b>end-to-end (E2E)</b> test brings up the full system of your app including all backend servers and client app. E2E tests will guarantee that data is sent to the client app and that the entire system functions correctly. <br /><br />Usually, in order to make the application UI functional, you need data from backend servers, so UI tests need to simulate the data but not necessarily the backend servers. In many cases UI tests are confused with E2E tests because E2E is very similar to manual test scenarios. However, debugging and stabilizing E2E tests is very difficult due to many variables like network flakiness, authentication against real servers, size of your system, etc. <br /><br /><div><a href="http://2.bp.blogspot.com/-ra84Z3ORWmg/VQyFLVWD76I/AAAAAAAAAI0/I63kDk2EF_k/s1600/image04.png"><img border="0" src="http://2.bp.blogspot.com/-ra84Z3ORWmg/VQyFLVWD76I/AAAAAAAAAI0/I63kDk2EF_k/s1600/image04.png" height="370" width="400"></a></div><br />When you use UI tests as E2E tests, you face the following problems:<br /><ul><li>Very large and slow tests.&#160;</li><li>High flakiness rate due to timeouts and memory issues.&#160;</li><li>Hard to debug/investigate failures.&#160;</li><li>Authentication issues (ex: authentication from automated tests is very tricky).</li></ul><br />Let&#8217;s see how these problems can be fixed using the following strategies.<br /><br /><span><b>Strategy 2: Hermetic UI Testing using Fake Servers</b></span><br /><br />In this strategy, you avoid network calls and external dependencies, but you need to provide your application with data that drives the UI. Update your application to communicate to a local server rather than external one, and create a fake local server that provides data to your application. You then need a mechanism to generate the data needed by your application. This can be done using various approaches depending on your system design. One approach is to record server responses and replay them in your fake server. <br /><br />Once you have hermetic UI tests talking to a local fake server, you should also have <a href="http://googletesting.blogspot.com/2012/10/hermetic-servers.html">server hermetic tests</a>. This way you split your E2E test into a server side test, a client side test, and an integration test to verify that the server and client are in sync (for more details on integration tests, see the backend testing section of <a href="http://googletesting.blogspot.com/2013/08/how-google-team-tests-mobile-apps.html">blog</a>). <br /><br />Now, the client test flow looks like: <br /><br /><div><a href="http://3.bp.blogspot.com/-TcTGohM5xQ4/VQyFIwtvlMI/AAAAAAAAAIk/QmIHKjJ6irU/s1600/image02.png"><img border="0" src="http://3.bp.blogspot.com/-TcTGohM5xQ4/VQyFIwtvlMI/AAAAAAAAAIk/QmIHKjJ6irU/s1600/image02.png" height="400" width="201"></a></div><br />While this approach drastically reduces the test size and flakiness rate, you still need to maintain a separate fake server as well as your test. Debugging is still not easy as you have two moving parts: the test and the local server. While test stability will be largely improved by this approach, the local server will cause some flakes. <br /><br />Let&#8217;s see how this could this be improved... <br /><br /><span><b>Strategy 3: Dependency Injection Design for Apps.  </b></span><br /><br />To remove the additional dependency of a fake server running on Android, you should use dependency injection in your application for swapping real module implementations with fake ones. One example is <a href="http://square.github.io/dagger/">Dagger</a>, or you can create your own dependency injection mechanism if needed. <br /><br />This will improve the testability of your app for both unit testing and UI testing, providing your tests with the ability to mock dependencies. In <a href="http://developer.android.com/tools/testing/testing_android.html">instrumentation testing</a>, the test apk and the app under test are loaded in the same process, so the test code has runtime access to the app code. Not only that, but you can also use classpath override (the fact that test classpath takes priority over app under test) to override a certain class and inject test fakes there. For example, To make your test hermetic, your app should support injection of the networking implementation. During testing, the test injects a fake networking implementation to your app, and this fake implementation will provide seeded data instead of communicating with backend servers.<br /><br /><div><a href="http://4.bp.blogspot.com/-wL-DjbOG7V4/VQyFKB5HM8I/AAAAAAAAAIs/xC9vexohL_Q/s1600/image03.png"><img border="0" src="http://4.bp.blogspot.com/-wL-DjbOG7V4/VQyFKB5HM8I/AAAAAAAAAIs/xC9vexohL_Q/s1600/image03.png" height="400" width="226"></a></div><br /><span><b>Strategy 4: Building Apps into Smaller Libraries </b></span><br /><br />If you want to scale your app into many modules and views, and plan to add more features while maintaining stable and fast builds/tests, then you should build your app into small components/libraries. Each library should have its own UI resources and user dependency management. This strategy not only enables mocking dependencies of your libraries for hermetic testing, but  also serves as an experimentation platform for various components of your application. <br /><br />Once you have small components with dependency injection support, you can build a test app for each component. <br /><br />The test apps bring up the actual UI of your libraries, fake data needed, and mock dependencies. Espresso tests will run against these test apps. This enables testing of smaller libraries in isolation. <br /><br />For example, let&#8217;s consider building smaller libraries for login and settings of your app. <br /><br /><div><a href="http://2.bp.blogspot.com/-yZbob6hsL2I/VQyFFie9n5I/AAAAAAAAAIU/Jt9sx2hprK4/s1600/image00.png"><img border="0" src="http://2.bp.blogspot.com/-yZbob6hsL2I/VQyFFie9n5I/AAAAAAAAAIU/Jt9sx2hprK4/s1600/image00.png" height="400" width="242"></a></div><br />The settings component test now looks like: <br /><br /><div><a href="http://2.bp.blogspot.com/-gYMFGkbFFME/VQyFHYt3rgI/AAAAAAAAAIc/CWoDna5AQx4/s1600/image01.png"><img border="0" src="http://2.bp.blogspot.com/-gYMFGkbFFME/VQyFHYt3rgI/AAAAAAAAAIc/CWoDna5AQx4/s1600/image01.png" height="400" width="227"></a></div><br /><span><b>Conclusion </b></span><br /><br />UI testing can be very challenging for rich apps on Android. Here are some UI testing lessons learned on the Google+ team:<br /><ol><li>Don&#8217;t write E2E tests instead of UI tests. Instead write unit tests and integration tests beside the UI tests.&#160;</li><li>Hermetic tests are the way to go.&#160;</li><li>Use dependency injection while designing your app.&#160;</li><li>Build your application into small libraries/modules, and test each one in isolation. You can then have a few integration tests to verify integration between components is correct .&#160;</li><li>Componentized UI tests have proven to be much faster than E2E and 99%+ stable. Fast and stable tests have proven to drastically improve developer productivity.</li></ol><br />]]></description>
				<content:encoded><![CDATA[<i>by Mona El Mahdy </i><br /><br /><span style="font-size: large;"><b>Overview </b></span><br /><br />This post reviews four strategies for Android UI testing with the goal of creating UI tests that are fast, reliable, and easy to debug.<br /><br />Before we begin, let’s not forget an important rule: whatever can be unit tested should be unit tested. <a href="http://robolectric.org/">Robolectric</a> and <a href="http://tools.android.com/tech-docs/unit-testing-support">gradle unit tests support</a> are great examples of unit test frameworks for Android. UI tests, on the other hand, are used to verify that your application returns the correct UI output in response to a sequence of user actions on a device. <a href="http://developer.android.com/tools/testing-support-library/index.html#Espresso">Espresso</a> is a great framework for running UI actions and verifications in the same process. For more details on the Espresso and UI Automator tools, please see: <a href="http://developer.android.com/tools/testing-support-library/index.html">test support libraries</a>. <br /><br />The Google+ team has performed many iterations of UI testing. Below we discuss the lessons learned during each strategy of UI testing. Stay tuned for more posts with more details and code samples. <br /><br /><span style="font-size: large;"><b>Strategy 1: Using an End-To-End Test as a UI Test </b></span><br /><br />Let’s start with some definitions. A <b>UI test</b> ensures that your application returns the correct UI output in response to a sequence of user actions on a device. An <b>end-to-end (E2E)</b> test brings up the full system of your app including all backend servers and client app. E2E tests will guarantee that data is sent to the client app and that the entire system functions correctly. <br /><br />Usually, in order to make the application UI functional, you need data from backend servers, so UI tests need to simulate the data but not necessarily the backend servers. In many cases UI tests are confused with E2E tests because E2E is very similar to manual test scenarios. However, debugging and stabilizing E2E tests is very difficult due to many variables like network flakiness, authentication against real servers, size of your system, etc. <br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-ra84Z3ORWmg/VQyFLVWD76I/AAAAAAAAAI0/I63kDk2EF_k/s1600/image04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-ra84Z3ORWmg/VQyFLVWD76I/AAAAAAAAAI0/I63kDk2EF_k/s1600/image04.png" height="370" width="400" /></a></div><br />When you use UI tests as E2E tests, you face the following problems:<br /><ul style="line-height: 1.3em; margin-bottom: 0px; margin-top: 0px; padding-bottom: 0px; padding-top: 0px;"><li>Very large and slow tests.&nbsp;</li><li>High flakiness rate due to timeouts and memory issues.&nbsp;</li><li>Hard to debug/investigate failures.&nbsp;</li><li>Authentication issues (ex: authentication from automated tests is very tricky).</li></ul><br />Let’s see how these problems can be fixed using the following strategies.<br /><br /><span style="font-size: large;"><b>Strategy 2: Hermetic UI Testing using Fake Servers</b></span><br /><br />In this strategy, you avoid network calls and external dependencies, but you need to provide your application with data that drives the UI. Update your application to communicate to a local server rather than external one, and create a fake local server that provides data to your application. You then need a mechanism to generate the data needed by your application. This can be done using various approaches depending on your system design. One approach is to record server responses and replay them in your fake server. <br /><br />Once you have hermetic UI tests talking to a local fake server, you should also have <a href="http://googletesting.blogspot.com/2012/10/hermetic-servers.html">server hermetic tests</a>. This way you split your E2E test into a server side test, a client side test, and an integration test to verify that the server and client are in sync (for more details on integration tests, see the backend testing section of <a href="http://googletesting.blogspot.com/2013/08/how-google-team-tests-mobile-apps.html">blog</a>). <br /><br />Now, the client test flow looks like: <br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-TcTGohM5xQ4/VQyFIwtvlMI/AAAAAAAAAIk/QmIHKjJ6irU/s1600/image02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-TcTGohM5xQ4/VQyFIwtvlMI/AAAAAAAAAIk/QmIHKjJ6irU/s1600/image02.png" height="400" width="201" /></a></div><br />While this approach drastically reduces the test size and flakiness rate, you still need to maintain a separate fake server as well as your test. Debugging is still not easy as you have two moving parts: the test and the local server. While test stability will be largely improved by this approach, the local server will cause some flakes. <br /><br />Let’s see how this could this be improved... <br /><br /><span style="font-size: large;"><b>Strategy 3: Dependency Injection Design for Apps.  </b></span><br /><br />To remove the additional dependency of a fake server running on Android, you should use dependency injection in your application for swapping real module implementations with fake ones. One example is <a href="http://square.github.io/dagger/">Dagger</a>, or you can create your own dependency injection mechanism if needed. <br /><br />This will improve the testability of your app for both unit testing and UI testing, providing your tests with the ability to mock dependencies. In <a href="http://developer.android.com/tools/testing/testing_android.html">instrumentation testing</a>, the test apk and the app under test are loaded in the same process, so the test code has runtime access to the app code. Not only that, but you can also use classpath override (the fact that test classpath takes priority over app under test) to override a certain class and inject test fakes there. For example, To make your test hermetic, your app should support injection of the networking implementation. During testing, the test injects a fake networking implementation to your app, and this fake implementation will provide seeded data instead of communicating with backend servers.<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-wL-DjbOG7V4/VQyFKB5HM8I/AAAAAAAAAIs/xC9vexohL_Q/s1600/image03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-wL-DjbOG7V4/VQyFKB5HM8I/AAAAAAAAAIs/xC9vexohL_Q/s1600/image03.png" height="400" width="226" /></a></div><br /><span style="font-size: large;"><b>Strategy 4: Building Apps into Smaller Libraries </b></span><br /><br />If you want to scale your app into many modules and views, and plan to add more features while maintaining stable and fast builds/tests, then you should build your app into small components/libraries. Each library should have its own UI resources and user dependency management. This strategy not only enables mocking dependencies of your libraries for hermetic testing, but  also serves as an experimentation platform for various components of your application. <br /><br />Once you have small components with dependency injection support, you can build a test app for each component. <br /><br />The test apps bring up the actual UI of your libraries, fake data needed, and mock dependencies. Espresso tests will run against these test apps. This enables testing of smaller libraries in isolation. <br /><br />For example, let’s consider building smaller libraries for login and settings of your app. <br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-yZbob6hsL2I/VQyFFie9n5I/AAAAAAAAAIU/Jt9sx2hprK4/s1600/image00.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-yZbob6hsL2I/VQyFFie9n5I/AAAAAAAAAIU/Jt9sx2hprK4/s1600/image00.png" height="400" width="242" /></a></div><br />The settings component test now looks like: <br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-gYMFGkbFFME/VQyFHYt3rgI/AAAAAAAAAIc/CWoDna5AQx4/s1600/image01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-gYMFGkbFFME/VQyFHYt3rgI/AAAAAAAAAIc/CWoDna5AQx4/s1600/image01.png" height="400" width="227" /></a></div><br /><span style="font-size: large;"><b>Conclusion </b></span><br /><br />UI testing can be very challenging for rich apps on Android. Here are some UI testing lessons learned on the Google+ team:<br /><ol style="line-height: 1.3em; margin-bottom: 0px; margin-top: 0px; padding-bottom: 0px; padding-top: 0px;"><li>Don’t write E2E tests instead of UI tests. Instead write unit tests and integration tests beside the UI tests.&nbsp;</li><li>Hermetic tests are the way to go.&nbsp;</li><li>Use dependency injection while designing your app.&nbsp;</li><li>Build your application into small libraries/modules, and test each one in isolation. You can then have a few integration tests to verify integration between components is correct .&nbsp;</li><li>Componentized UI tests have proven to be much faster than E2E and 99%+ stable. Fast and stable tests have proven to drastically improve developer productivity.</li></ol><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/android-ui-automated-testing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>The First Annual Testing on the Toilet Awards</title>
		<link>https://googledata.org/google-testing/the-first-annual-testing-on-the-toilet-awards/</link>
		<comments>https://googledata.org/google-testing/the-first-annual-testing-on-the-toilet-awards/#comments</comments>
		<pubDate>Tue, 03 Feb 2015 16:50:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=3cf7a52f667d3d964670861e791600ed</guid>
		<description><![CDATA[<i>By Andrew Trenk </i><br /><br />The Testing on the Toilet (TotT) series was <a href="http://googletesting.blogspot.com/2007/01/introducing-testing-on-toilet.html">created</a> in 2006 as a way to spread unit-testing knowledge across Google by posting flyers in bathroom stalls. It quickly became a part of Google culture and is still going strong today, with new episodes published every week and read in hundreds of bathrooms by thousands of engineers in Google offices across the world. Initially focused on content related to testing, TotT now covers a variety of technical topics, such as tips on writing cleaner code and ways to prevent security bugs. <br /><br />While TotT episodes often have a big impact on many engineers across Google, until now we never did anything to formally thank authors for their contributions. To fix that, we decided to honor the most popular TotT episodes of 2014 by establishing the Testing on the Toilet Awards. The winners were chosen through a vote that was open to all Google engineers. The Google Testing Blog is proud to present the winners that were posted on this blog (there were two additional winners that weren&#8217;t posted on this blog since we only post testing-related TotT episodes). <br /><br />And the winners are ... <br /><br /><b>Erik Kuefler:</b> <a href="http://googletesting.blogspot.com/2014/04/testing-on-toilet-test-behaviors-not.html">Test Behaviors, Not Methods</a> and <a href="http://googletesting.blogspot.com/2014/07/testing-on-toilet-dont-put-logic-in.html">Don't Put Logic in Tests</a>&#160; <br /><b>Alex Eagle:</b> <a href="http://googletesting.blogspot.com/2015/01/testing-on-toilet-change-detector-tests.html">Change-Detector Tests Considered Harmful</a><br /><br />The authors of these episodes received their very own Flushy trophy, which they can proudly display on their desks. <br /><br /><div><a href="http://3.bp.blogspot.com/-AuTtNwV5Fp0/VND7kbIbybI/AAAAAAAAAH0/jvShp-Lgijw/s1600/image00.jpg"><img border="0" src="http://3.bp.blogspot.com/-AuTtNwV5Fp0/VND7kbIbybI/AAAAAAAAAH0/jvShp-Lgijw/s1600/image00.jpg" height="320" width="212"></a></div><br /><br />(The logo on the trophy is the same one we put on the printed version of each TotT episode, which you can see by looking for the &#8220;printer-friendly version&#8221; link in the <a href="http://googletesting.blogspot.com/search/label/TotT">TotT blog posts</a>). <br /><br />Congratulations to the winners! <br /><br />]]></description>
				<content:encoded><![CDATA[<i>By Andrew Trenk </i><br /><br />The Testing on the Toilet (TotT) series was <a href="http://googletesting.blogspot.com/2007/01/introducing-testing-on-toilet.html">created</a> in 2006 as a way to spread unit-testing knowledge across Google by posting flyers in bathroom stalls. It quickly became a part of Google culture and is still going strong today, with new episodes published every week and read in hundreds of bathrooms by thousands of engineers in Google offices across the world. Initially focused on content related to testing, TotT now covers a variety of technical topics, such as tips on writing cleaner code and ways to prevent security bugs. <br /><br />While TotT episodes often have a big impact on many engineers across Google, until now we never did anything to formally thank authors for their contributions. To fix that, we decided to honor the most popular TotT episodes of 2014 by establishing the Testing on the Toilet Awards. The winners were chosen through a vote that was open to all Google engineers. The Google Testing Blog is proud to present the winners that were posted on this blog (there were two additional winners that weren’t posted on this blog since we only post testing-related TotT episodes). <br /><br />And the winners are ... <br /><br /><b>Erik Kuefler:</b> <a href="http://googletesting.blogspot.com/2014/04/testing-on-toilet-test-behaviors-not.html">Test Behaviors, Not Methods</a> and <a href="http://googletesting.blogspot.com/2014/07/testing-on-toilet-dont-put-logic-in.html">Don't Put Logic in Tests</a>&nbsp; <br /><b>Alex Eagle:</b> <a href="http://googletesting.blogspot.com/2015/01/testing-on-toilet-change-detector-tests.html">Change-Detector Tests Considered Harmful</a><br /><br />The authors of these episodes received their very own Flushy trophy, which they can proudly display on their desks. <br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-AuTtNwV5Fp0/VND7kbIbybI/AAAAAAAAAH0/jvShp-Lgijw/s1600/image00.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-AuTtNwV5Fp0/VND7kbIbybI/AAAAAAAAAH0/jvShp-Lgijw/s1600/image00.jpg" height="320" width="212" /></a></div><br /><br />(The logo on the trophy is the same one we put on the printed version of each TotT episode, which you can see by looking for the “printer-friendly version” link in the <a href="http://googletesting.blogspot.com/search/label/TotT">TotT blog posts</a>). <br /><br />Congratulations to the winners! <br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/the-first-annual-testing-on-the-toilet-awards/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Testing on the Toilet: Change-Detector Tests Considered Harmful</title>
		<link>https://googledata.org/google-testing/testing-on-the-toilet-change-detector-tests-considered-harmful/</link>
		<comments>https://googledata.org/google-testing/testing-on-the-toilet-change-detector-tests-considered-harmful/#comments</comments>
		<pubDate>Wed, 28 Jan 2015 00:42:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=9a94142ae086c345610f7f0f0dec7487</guid>
		<description><![CDATA[<i>by Alex Eagle <br /><br />This article was adapted from a  <a href="http://googletesting.blogspot.com/2007/01/introducing-testing-on-toilet.html">Google Testing on the Toilet</a> (TotT) episode. You can download a  <a href="https://docs.google.com/document/d/13k8AsgYdF-2TJx9QIHHvPiuV3JMbsrMLkWmmjdYBLVg/edit?usp=sharing">printer-friendly version</a> of this TotT episode and post it in your office. </i><br /><br />You have just finished refactoring some code without modifying its behavior. Then you run the tests before committing and&#8230; a bunch of unit tests are failing. <span><b>While fixing the tests, you get a sense that you are wasting time by mechanically applying the same transformation to many tests.</b></span> Maybe you introduced a parameter in a method, and now must update 100 callers of that method in tests to pass an empty string. <br /><br /><span><b>What does it look like to write tests mechanically?</b></span> Here is an absurd but obvious way:<br /><pre><span>// Production code:</span><br />def abs(i: Int)<br /><span>return</span> (i &#60; 0) ? i * -1 : i<br /><br /><span>// Test code:</span><br /><span>for</span> (line: String in File(prod_source).read_lines())<br /><span>switch</span> (line.number)<br />    1: assert line.content equals def abs(i: Int)<br />    2: assert line.content equals   <span>return</span> (i &#60; 0) ? i * -1 : i</pre><br /><b><span>That test is clearly not useful</span></b>: it contains an exact copy of the code under test and acts like a checksum. <b><span>A correct or incorrect program is equally likely to pass</span></b> a test that is a derivative of the code under test. No one is really writing tests like that, but how different is it from this next example?<br /><pre><span>// Production code:</span><br />def process(w: Work)<br />  firstPart.process(w)<br />  secondPart.process(w)<br /><br /><span>// Test code:</span><br />part1 = mock(FirstPart)<br />part2 = mock(SecondPart)<br />w = Work()<br />Processor(part1, part2).process(w)<br />verify_in_order<br />  was_called part1.process(w)<br />  was_called part2.process(w)</pre><br />It is tempting to write a test like this because it requires little thought and will run quickly. <b><span>This is a change-detector test</span></b>&#8212;it is a transformation of the same information in the code under test&#8212;and <b><span>it breaks in response to any change to the production code, without verifying correct behavior</span></b> of either the original or modified production code. <br /><br /><b><span>Change detectors provide negative value</span></b>, since the tests do not catch any defects, and the added maintenance cost slows down development. These tests should be re-written or deleted. <br /><br />]]></description>
				<content:encoded><![CDATA[<i>by Alex Eagle <br /><br />This article was adapted from a  <a href="http://googletesting.blogspot.com/2007/01/introducing-testing-on-toilet.html">Google Testing on the Toilet</a> (TotT) episode. You can download a  <a href="https://docs.google.com/document/d/13k8AsgYdF-2TJx9QIHHvPiuV3JMbsrMLkWmmjdYBLVg/edit?usp=sharing">printer-friendly version</a> of this TotT episode and post it in your office. </i><br /><br />You have just finished refactoring some code without modifying its behavior. Then you run the tests before committing and… a bunch of unit tests are failing. <span style="color: purple;"><b>While fixing the tests, you get a sense that you are wasting time by mechanically applying the same transformation to many tests.</b></span> Maybe you introduced a parameter in a method, and now must update 100 callers of that method in tests to pass an empty string. <br /><br /><span style="color: purple;"><b>What does it look like to write tests mechanically?</b></span> Here is an absurd but obvious way:<br /><pre style="background: #cfe2f3; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;"><span style="color: #4f8f00;">// Production code:</span><br />def abs(i: Int)<br />  <span style="color: #0433ff;">return</span> (i &lt; 0) ? i * -1 : i<br /><br /><span style="color: #4f8f00;">// Test code:</span><br /><span style="color: #0433ff;">for</span> (line: String in File(prod_source).read_lines())<br />  <span style="color: #0433ff;">switch</span> (line.number)<br />    1: assert line.content equals def abs(i: Int)<br />    2: assert line.content equals   <span style="color: #0433ff;">return</span> (i &lt; 0) ? i * -1 : i</pre><br /><b><span style="color: purple;">That test is clearly not useful</span></b>: it contains an exact copy of the code under test and acts like a checksum. <b><span style="color: purple;">A correct or incorrect program is equally likely to pass</span></b> a test that is a derivative of the code under test. No one is really writing tests like that, but how different is it from this next example?<br /><pre style="background: #cfe2f3; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;"><span style="color: #4f8f00;">// Production code:</span><br />def process(w: Work)<br />  firstPart.process(w)<br />  secondPart.process(w)<br /><br /><span style="color: #4f8f00;">// Test code:</span><br />part1 = mock(FirstPart)<br />part2 = mock(SecondPart)<br />w = Work()<br />Processor(part1, part2).process(w)<br />verify_in_order<br />  was_called part1.process(w)<br />  was_called part2.process(w)</pre><br />It is tempting to write a test like this because it requires little thought and will run quickly. <b><span style="color: purple;">This is a change-detector test</span></b>—it is a transformation of the same information in the code under test—and <b><span style="color: purple;">it breaks in response to any change to the production code, without verifying correct behavior</span></b> of either the original or modified production code. <br /><br /><b><span style="color: purple;">Change detectors provide negative value</span></b>, since the tests do not catch any defects, and the added maintenance cost slows down development. These tests should be re-written or deleted. <br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/testing-on-the-toilet-change-detector-tests-considered-harmful/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Testing on the Toilet: Prefer Testing Public APIs Over Implementation-Detail Classes</title>
		<link>https://googledata.org/google-testing/testing-on-the-toilet-prefer-testing-public-apis-over-implementation-detail-classes/</link>
		<comments>https://googledata.org/google-testing/testing-on-the-toilet-prefer-testing-public-apis-over-implementation-detail-classes/#comments</comments>
		<pubDate>Wed, 14 Jan 2015 17:30:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=b1e687bba17240a35d8c00fa75f5434d</guid>
		<description><![CDATA[<i>by Andrew Trenk <br /><br />This article was adapted from a  <a href="http://googletesting.blogspot.com/2007/01/introducing-testing-on-toilet.html">Google Testing on the Toilet</a> (TotT) episode. You can download a  <a href="https://docs.google.com/document/d/1ILEpaxZ9ntMEXNQuL-q4jWHF0QOAMo45elmomn29cZg/edit?usp=sharing">printer-friendly version</a> of this TotT episode and post it in your office. </i><br /><br /><span><b>Does this class need to have tests?  </b></span><br /><pre><span>class</span> UserInfoValidator {<br /><span>public</span> <span>void</span> validate(UserInfo info) {<br /><span>if</span> (info.getDateOfBirth().isInFuture()) { <span>throw</span> <span>new</span> ValidationException()); }<br />  }<br />}</pre>Its method has some logic, so it may be good idea to test it. But <span><b>what if its only user looks like this?  </b></span><br /><pre><span>public</span> <span>class</span> UserInfoService {<br /><span>private</span> UserInfoValidator validator;<br /><span>public</span> <span>void</span> save(UserInfo info) {<br />    validator.validate(info); <span>// Throw an exception if the value is invalid.</span><br />    writeToDatabase(info);   <br />  }<br />}</pre>The answer is: <span><b>it probably doesn&#8217;t need tests</b></span>, since all paths can be tested through <span>UserInfoService</span>. The key distinction is that <span><b>the class is an implementation detail, not a public API</b></span>.<br /><br /><b><span>A public API can be called by any number of users</span></b>, who can pass in any possible combination of inputs to its methods. <b><span>You want to make sure these are well-tested</span></b>, which ensures users won&#8217;t see issues when they use the API. Examples of public APIs include classes that are used in a different part of a codebase (e.g., a server-side class that&#8217;s used by the client-side) and common utility classes that are used throughout a codebase. <br /><br /><b><span>An implementation-detail class exists only to support public APIs</span></b> and is called by a very limited number of users (often only one). <b><span>These classes can sometimes be tested indirectly</span></b> by testing the public APIs that use them.  <br /><br /><b><span>Testing implementation-detail classes is still useful in many cases</span></b>, such as if the class is complex or if the tests would be difficult to write for the public API class. When you do test them, <b><span>they often don&#8217;t need to be tested in as much depth as a public API,</span></b> since some inputs may never be passed into their methods (in the above code sample, if <span>UserInfoService</span> ensured that <span>UserInfo</span> were never <span>null</span>, then it wouldn&#8217;t be useful to test what happens when <span>null</span> is passed as an argument to <span>UserInfoValidator.validate</span>, since it would never happen). <br /><br />Implementation-detail classes can sometimes be thought of as private methods that happen to be in a separate class, since you typically don&#8217;t want to test private methods directly either. <b><span>You should also try to restrict the visibility of implementation-detail classes,</span></b> such as by making them package-private in Java. <br /><br /><b><span>Testing implementation-detail classes too often leads to a couple problems</span></b>: <br /><br />- <b><span>Code is harder to maintain since you need to update tests more often</span></b>, such as when changing a method signature of an implementation-detail class or even when doing a refactoring. If testing is done only through public APIs, these changes wouldn&#8217;t affect the tests at all. <br /><br />- <b><span>If you test a behavior only through an implementation-detail class, you may get false confidence in your code</span></b>, since the same code path may not work properly when exercised through the public API. <b><span>You also have to be more careful when refactoring</span></b>, since it can be harder to ensure that all the behavior of the public API will be preserved if not all paths are tested through the public API.]]></description>
				<content:encoded><![CDATA[<i>by Andrew Trenk <br /><br />This article was adapted from a  <a href="http://googletesting.blogspot.com/2007/01/introducing-testing-on-toilet.html">Google Testing on the Toilet</a> (TotT) episode. You can download a  <a href="https://docs.google.com/document/d/1ILEpaxZ9ntMEXNQuL-q4jWHF0QOAMo45elmomn29cZg/edit?usp=sharing">printer-friendly version</a> of this TotT episode and post it in your office. </i><br /><br /><span style="color: purple;"><b>Does this class need to have tests?  </b></span><br /><pre style="background: #d9ead3; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;"><span style="color: #945200;">class</span> UserInfoValidator {<br />  <span style="color: #945200;">public</span> <span style="color: #945200;">void</span> validate(UserInfo info) {<br />    <span style="color: #945200;">if</span> (info.getDateOfBirth().isInFuture()) { <span style="color: #945200;">throw</span> <span style="color: #945200;">new</span> ValidationException()); }<br />  }<br />}</pre>Its method has some logic, so it may be good idea to test it. But <span style="color: purple;"><b>what if its only user looks like this?  </b></span><br /><pre style="background: #d9ead3; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;"><span style="color: #945200;">public</span> <span style="color: #945200;">class</span> UserInfoService {<br />  <span style="color: #945200;">private</span> UserInfoValidator validator;<br />  <span style="color: #945200;">public</span> <span style="color: #945200;">void</span> save(UserInfo info) {<br />    validator.validate(info); <span style="color: #0096ff;">// Throw an exception if the value is invalid.</span><br />    writeToDatabase(info);   <br />  }<br />}</pre>The answer is: <span style="color: purple;"><b>it probably doesn’t need tests</b></span>, since all paths can be tested through <span style="font-family: Courier New, Courier, monospace;">UserInfoService</span>. The key distinction is that <span style="color: purple;"><b>the class is an implementation detail, not a public API</b></span>.<br /><br /><b><span style="color: purple;">A public API can be called by any number of users</span></b>, who can pass in any possible combination of inputs to its methods. <b><span style="color: purple;">You want to make sure these are well-tested</span></b>, which ensures users won’t see issues when they use the API. Examples of public APIs include classes that are used in a different part of a codebase (e.g., a server-side class that’s used by the client-side) and common utility classes that are used throughout a codebase. <br /><br /><b><span style="color: purple;">An implementation-detail class exists only to support public APIs</span></b> and is called by a very limited number of users (often only one). <b><span style="color: purple;">These classes can sometimes be tested indirectly</span></b> by testing the public APIs that use them.  <br /><br /><b><span style="color: purple;">Testing implementation-detail classes is still useful in many cases</span></b>, such as if the class is complex or if the tests would be difficult to write for the public API class. When you do test them, <b><span style="color: purple;">they often don’t need to be tested in as much depth as a public API,</span></b> since some inputs may never be passed into their methods (in the above code sample, if <span style="font-family: Courier New, Courier, monospace;">UserInfoService</span> ensured that <span style="font-family: Courier New, Courier, monospace;">UserInfo</span> were never <span style="font-family: Courier New, Courier, monospace;">null</span>, then it wouldn’t be useful to test what happens when <span style="font-family: Courier New, Courier, monospace;">null</span> is passed as an argument to <span style="font-family: Courier New, Courier, monospace;">UserInfoValidator.validate</span>, since it would never happen). <br /><br />Implementation-detail classes can sometimes be thought of as private methods that happen to be in a separate class, since you typically don’t want to test private methods directly either. <b><span style="color: purple;">You should also try to restrict the visibility of implementation-detail classes,</span></b> such as by making them package-private in Java. <br /><br /><b><span style="color: purple;">Testing implementation-detail classes too often leads to a couple problems</span></b>: <br /><br />- <b><span style="color: purple;">Code is harder to maintain since you need to update tests more often</span></b>, such as when changing a method signature of an implementation-detail class or even when doing a refactoring. If testing is done only through public APIs, these changes wouldn’t affect the tests at all. <br /><br />- <b><span style="color: purple;">If you test a behavior only through an implementation-detail class, you may get false confidence in your code</span></b>, since the same code path may not work properly when exercised through the public API. <b><span style="color: purple;">You also have to be more careful when refactoring</span></b>, since it can be harder to ensure that all the behavior of the public API will be preserved if not all paths are tested through the public API.]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/testing-on-the-toilet-prefer-testing-public-apis-over-implementation-detail-classes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Testing on the Toilet: Truth: a fluent assertion framework</title>
		<link>https://googledata.org/google-testing/testing-on-the-toilet-truth-a-fluent-assertion-framework/</link>
		<comments>https://googledata.org/google-testing/testing-on-the-toilet-truth-a-fluent-assertion-framework/#comments</comments>
		<pubDate>Fri, 19 Dec 2014 18:25:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=fbc1c4a27d93a13c37a996869d86021d</guid>
		<description><![CDATA[by Dori Reuveni and Kurt Alfred Kluever This article was adapted from a  Google Testing on the Toilet (TotT) episode. You can download a  printer-friendly version of this TotT episode and post it in your office. As engineers, we spend most of our time ...]]></description>
				<content:encoded><![CDATA[<i>by Dori Reuveni and Kurt Alfred Kluever <br /><br />This article was adapted from a  <a href="http://googletesting.blogspot.com/2007/01/introducing-testing-on-toilet.html">Google Testing on the Toilet</a> (TotT) episode. You can download a  <a href="https://docs.google.com/document/d/1TyLthjSGeELWVloxx2hI9l57pNRSN4UVAaNdB7H4Ctg/edit?usp=sharing">printer-friendly version</a> of this TotT episode and post it in your office. </i><br /><br /><b><span style="color: purple;">As engineers, we spend most of our time reading existing code, rather than writing new code.</span></b> Therefore, we must make sure we always write clean, readable code. The same goes for our tests; we need a way to clearly express our test assertions.<br /><br /><b><span style="color: purple;">Truth is an open source, fluent testing framework for Java designed to make your test assertions and failure messages more readable.</span></b> The fluent API makes reading (and writing) test assertions much more natural, prose-like, and discoverable in your IDE via autocomplete. For example, compare how the following assertion reads with JUnit vs. Truth:<br /><pre style="background: #cfe2f3; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;"><b>assertEquals</b>(<span style="color: #ff2600;">"March"</span>, monthMap.get(3));          <span style="color: #4f8f00;">// JUnit</span><br /><b>assertThat</b>(monthMap).<b>containsEntry</b>(3, <span style="color: #ff2600;">"March"</span>);  <span style="color: #4f8f00;">// Truth</span></pre>Both statements are asserting the same thing, but the assertion written with Truth can be easily read from left to right, while the JUnit example requires "mental backtracking".<br /><br /><b><span style="color: purple;">Another benefit of Truth over JUnit is the addition of useful default failure messages</span></b>. For example:<br /><pre style="background: #cfe2f3; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;">ImmutableSet&lt;String&gt; colors = ImmutableSet.of(<span style="color: #ff2600;">"red"</span>, <span style="color: #ff2600;">"green"</span>, <span style="color: #ff2600;">"blue"</span>, <span style="color: #ff2600;">"yellow"</span>);<br /><b>assertTrue</b>(colors.contains(<span style="color: #ff2600;">"orange"</span>));  <span style="color: #4f8f00;">// JUnit</span><br /><b>assertThat</b>(colors).<b>contains</b>(<span style="color: #ff2600;">"orange"</span>);  <span style="color: #4f8f00;">// Truth</span></pre>In this example, both assertions will fail, but <b><span style="color: purple;">JUnit will not provide a useful failure message</span></b>. However, <span style="color: purple;"><b>Truth will provide a clear and concise failure message</b></span>:<br /><br /><span style="font-family: Courier New, Courier, monospace;">AssertionError: &lt;[red, green, blue, yellow]&gt; should have contained &lt;orange&gt;</span><br /><br /><b><span style="color: purple;">Truth already supports specialized assertions for most of the common JDK types</span></b> (Objects, primitives, arrays, Strings, Classes, Comparables, Iterables, Collections, Lists, Sets, Maps, etc.), as well as some Guava types (Optionals). Additional support for other popular types is planned as well (Throwables, Iterators, Multimaps, UnsignedIntegers, UnsignedLongs, etc.). <br /><br /><b><span style="color: purple;">Truth is also user-extensible: you can easily write a Truth subject to make fluent assertions about your own custom types</span></b>. By creating your own custom subject, both your assertion API and your failure messages can be domain-specific.  <br /><br /><b><span style="color: purple;">Truth's goal is not to replace JUnit assertions, but to improve the readability of complex assertions and their failure messages</span></b>. JUnit assertions and Truth assertions can (and often do) live side by side in tests. <br /><br /><b><span style="color: purple;">To get started with Truth, check out</span></b> <a href="http://google.github.io/truth/">http://google.github.io/truth/</a><br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/testing-on-the-toilet-truth-a-fluent-assertion-framework/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>GTAC 2014 Wrap-up</title>
		<link>https://googledata.org/google-testing/gtac-2014-wrap-up/</link>
		<comments>https://googledata.org/google-testing/gtac-2014-wrap-up/#comments</comments>
		<pubDate>Fri, 05 Dec 2014 00:24:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=096b91c0a12ec3b39172479b1d16ce8c</guid>
		<description><![CDATA[by Anthony Vallone on behalf of the GTAC Committee On October 28th and 29th, GTAC 2014, the eighth GTAC (Google Test Automation Conference), was held at the beautiful Google Kirkland office. The conference was completely packed with presenters and atte...]]></description>
				<content:encoded><![CDATA[<i>by Anthony Vallone on behalf of the GTAC Committee </i><br /><br />On October 28th and 29th, <a href="https://developers.google.com/google-test-automation-conference/2014/">GTAC 2014</a>, the eighth GTAC (Google Test Automation Conference), was held at the beautiful <a href="http://www.google.com/about/careers/locations/seattle-kirkland/">Google Kirkland office</a>. The conference was completely packed with presenters and attendees from all over the world (<i>Argentina, Australia, Canada, China, many European countries, India, Israel, Korea, New Zealand, Puerto Rico, Russia, Taiwan, and many US states</i>), bringing with them a huge diversity of experiences.<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-AsIoO6UVjSg/VID5DtgkaeI/AAAAAAAAAHM/VJMsLWzhKZw/s1600/gtac-reception.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-AsIoO6UVjSg/VID5DtgkaeI/AAAAAAAAAHM/VJMsLWzhKZw/s1600/gtac-reception.jpg" height="266" width="400" /></a></div><br />Speakers from numerous companies and universities (<i>Adobe, American Express, Comcast, Dropbox, Facebook, FINRA, Google, HP, Medidata Solutions, Mozilla, Netflix, Orange, and University of Waterloo</i>) spoke on a variety of interesting and cutting edge test automation topics.<br /><br />All of the <a href="https://developers.google.com/google-test-automation-conference/2014/presentations">slides and video recordings</a> are now available on the GTAC site. Photos will be available soon as well.<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-vFVJPsUDf5w/VID5J4eHzRI/AAAAAAAAAHU/td0jYOzgLlM/s1600/gtac-crowd.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-vFVJPsUDf5w/VID5J4eHzRI/AAAAAAAAAHU/td0jYOzgLlM/s1600/gtac-crowd.jpg" height="266" width="400" /></a></div><br />This was our most popular GTAC to date, with over 1,500 applicants and almost 200 of those for speaking. About 250 people filled our venue to capacity, and the live stream had a peak of about 400 concurrent viewers with 4,700 playbacks during the event. And, there was plenty of interesting <a href="https://twitter.com/search?q=%23gtac2014">Twitter</a> and <a href="https://plus.google.com/u/0/explore/gtac2014">Google+</a> activity during the event.<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-99JJwZlZacE/VID5LooJXyI/AAAAAAAAAHc/u5QJvNmlTiw/s1600/gtac-eat.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-99JJwZlZacE/VID5LooJXyI/AAAAAAAAAHc/u5QJvNmlTiw/s1600/gtac-eat.jpg" height="266" width="400" /></a></div><br />Our goal in hosting GTAC is to make the conference highly relevant and useful for, not only attendees, but the larger test engineering community as a whole. Our post-conference survey shows that we are close to achieving that goal: <br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-9B3NGNXAyyI/VID5NcheskI/AAAAAAAAAHk/0WPeJvqiPKU/s1600/gtac-stats.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-9B3NGNXAyyI/VID5NcheskI/AAAAAAAAAHk/0WPeJvqiPKU/s1600/gtac-stats.png" height="154" width="640" /></a></div><br /><br />If you have any suggestions on how we can improve, please comment on this post. <br /><br />Thank you to all the <a href="https://developers.google.com/google-test-automation-conference/2014/speakers">speakers</a>, attendees, and online viewers who made this a special event once again. To receive announcements about the next GTAC, subscribe to the <a href="http://googletesting.blogspot.com/">Google Testing Blog</a>. <br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/gtac-2014-wrap-up/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Protractor: Angular testing made easy</title>
		<link>https://googledata.org/google-testing/protractor-angular-testing-made-easy/</link>
		<comments>https://googledata.org/google-testing/protractor-angular-testing-made-easy/#comments</comments>
		<pubDate>Sun, 30 Nov 2014 17:46:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=cbd3bf2958b53751e8878580c24ec4bc</guid>
		<description><![CDATA[<i>By Hank Duan, Julie Ralph, and Arif Sukoco in Seattle </i><br /><br />Have you worked with WebDriver but been frustrated with all the waits needed for WebDriver to sync with the website, causing flakes and prolonged test times? If you are working with AngularJS apps, then Protractor is the right tool for you. <br /><br />Protractor (<a href="http://protractortest.org/">protractortest.org</a>) is an end-to-end test framework specifically for AngularJS apps. It was built by a team in Google and released to open source. Protractor is built on top of WebDriverJS and includes important improvements tailored for AngularJS apps. Here are some of Protractor&#8217;s key benefits:<br /><br /><ul><li><b>You don&#8217;t need to add waits or sleeps to your test</b>. Protractor can communicate with your AngularJS app automatically and execute the next step in your test the moment the webpage finishes pending tasks, so you don&#8217;t have to worry about waiting for your test and webpage to sync.&#160;</li><li><b>It supports Angular-specific locator strategies</b> (e.g., binding, model, repeater) as well as native WebDriver locator strategies (e.g., ID, CSS selector, XPath). This allows you to test Angular-specific elements without any setup effort on your part.&#160;</li><li><b>It is easy to set up page objects</b>. Protractor does not execute WebDriver commands until an action is needed (e.g., get, sendKeys, click). This way you can set up page objects so tests can manipulate page elements without touching the HTML.&#160;</li><li><b>It uses Jasmine</b>, the framework you use to write AngularJS unit tests, <b>and Javascript</b>, the same language you use to write AngularJS apps.</li></ul><br />Follow these simple steps, and in minutes, you will have you first Protractor test running:  <br /><br /><b>1) Set up environment </b><br /><br />Install the command line tools &#8216;protractor&#8217; and &#8216;webdriver-manager&#8217; using npm:<br /><pre>npm install -g protractor</pre><br />Start up an instance of a selenium server:<br /><pre>webdriver-manager update &#38; webdriver-manager start</pre><br />This downloads the necessary binary, and starts a new webdriver session listening on <a href="http://localhost:4444/">http://localhost:4444</a>. <br /><br /><b>2) Write your test</b><br /><pre><span>// It is a good idea to use page objects to modularize your testing logic</span><br />var angularHomepage = {<br />  nameInput : element(by.model(<span>'yourName'</span>)),<br />  greeting : element(by.binding(<span>'yourName'</span>)),<br />  get : function() {<br />    browser.get(<span>'index.html'</span>);<br />  },<br />  setName : function(name) {<br /><span>this</span>.nameInput.sendKeys(name);<br />  }<br />};<br /><br /><span>// Here we are using the Jasmine test framework </span><br /><span>// See http://jasmine.github.io/2.0/introduction.html for more details</span><br />describe(<span>'angularjs homepage'</span>, function() {<br />  it(<span>'should greet the named user'</span>, function(){<br />    angularHomepage.get();<br />    angularHomepage.setName(<span>'Julie'</span>);<br />    expect(angularHomepage.greeting.getText()).<br />        toEqual(<span>'Hello Julie!'</span>);<br />  });<br />});</pre><br />3) Write a Protractor configuration file to specify the environment under which you want your test to run:<br /><pre>exports.config = {<br />  seleniumAddress: <span>'http://localhost:4444/wd/hub'</span>,<br /><br />  specs: [<span>'testFolder/*'</span>],<br /><br />  multiCapabilities: [{<br /><span>'browserName'</span>: <span>'chrome'</span>,<br /><span>// browser-specific tests</span><br />    specs: <span>'chromeTests/*'</span> <br />  }, {<br /><span>'browserName'</span>: <span>'firefox'</span>,<br /><span>// run tests in parallel</span><br />    shardTestFiles: <span>true</span> <br />  }],<br /><br />  baseUrl: <span>'http://www.angularjs.org'</span>,<br />};</pre><br />4) Run the test: <br /><br />Start the test with the command: <br /><pre>protractor conf.js</pre><br />The test output should be: <br /><pre>1 test, 1 assertions, 0 failures</pre><br /><br />If you want to learn more, here&#8217;s a full tutorial that highlights all of Protractor&#8217;s features: <a href="http://angular.github.io/protractor/#/tutorial">http://angular.github.io/protractor/#/tutorial </a><br /><br />]]></description>
				<content:encoded><![CDATA[<i>By Hank Duan, Julie Ralph, and Arif Sukoco in Seattle </i><br /><br />Have you worked with WebDriver but been frustrated with all the waits needed for WebDriver to sync with the website, causing flakes and prolonged test times? If you are working with AngularJS apps, then Protractor is the right tool for you. <br /><br />Protractor (<a href="http://protractortest.org/">protractortest.org</a>) is an end-to-end test framework specifically for AngularJS apps. It was built by a team in Google and released to open source. Protractor is built on top of WebDriverJS and includes important improvements tailored for AngularJS apps. Here are some of Protractor’s key benefits:<br /><br /><ul style="line-height: 1.3em; margin-bottom: 0px; margin-top: 0px; padding-bottom: 0px; padding-top: 0px;"><li><b>You don’t need to add waits or sleeps to your test</b>. Protractor can communicate with your AngularJS app automatically and execute the next step in your test the moment the webpage finishes pending tasks, so you don’t have to worry about waiting for your test and webpage to sync.&nbsp;</li><li><b>It supports Angular-specific locator strategies</b> (e.g., binding, model, repeater) as well as native WebDriver locator strategies (e.g., ID, CSS selector, XPath). This allows you to test Angular-specific elements without any setup effort on your part.&nbsp;</li><li><b>It is easy to set up page objects</b>. Protractor does not execute WebDriver commands until an action is needed (e.g., get, sendKeys, click). This way you can set up page objects so tests can manipulate page elements without touching the HTML.&nbsp;</li><li><b>It uses Jasmine</b>, the framework you use to write AngularJS unit tests, <b>and Javascript</b>, the same language you use to write AngularJS apps.</li></ul><br />Follow these simple steps, and in minutes, you will have you first Protractor test running:  <br /><br /><b>1) Set up environment </b><br /><br />Install the command line tools ‘protractor’ and ‘webdriver-manager’ using npm:<br /><pre style="background: #f0f0f0; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;">npm install -g protractor</pre><br />Start up an instance of a selenium server:<br /><pre style="background: #f0f0f0; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;">webdriver-manager update &amp; webdriver-manager start</pre><br />This downloads the necessary binary, and starts a new webdriver session listening on <a href="http://localhost:4444/">http://localhost:4444</a>. <br /><br /><b>2) Write your test</b><br /><pre style="background: #f0f0f0; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;"><span style="color: #4f8f00;">// It is a good idea to use page objects to modularize your testing logic</span><br />var angularHomepage = {<br />  nameInput : element(by.model(<span style="color: #ff2600;">'yourName'</span>)),<br />  greeting : element(by.binding(<span style="color: #ff2600;">'yourName'</span>)),<br />  get : function() {<br />    browser.get(<span style="color: #ff2600;">'index.html'</span>);<br />  },<br />  setName : function(name) {<br />    <span style="color: #0433ff;">this</span>.nameInput.sendKeys(name);<br />  }<br />};<br /><br /><span style="color: #4f8f00;">// Here we are using the Jasmine test framework </span><br /><span style="color: #4f8f00;">// See http://jasmine.github.io/2.0/introduction.html for more details</span><br />describe(<span style="color: #ff2600;">'angularjs homepage'</span>, function() {<br />  it(<span style="color: #ff2600;">'should greet the named user'</span>, function(){<br />    angularHomepage.get();<br />    angularHomepage.setName(<span style="color: #ff2600;">'Julie'</span>);<br />    expect(angularHomepage.greeting.getText()).<br />        toEqual(<span style="color: #ff2600;">'Hello Julie!'</span>);<br />  });<br />});</pre><br />3) Write a Protractor configuration file to specify the environment under which you want your test to run:<br /><pre style="background: #f0f0f0; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;">exports.config = {<br />  seleniumAddress: <span style="color: #ff2600;">'http://localhost:4444/wd/hub'</span>,<br />  <br />  specs: [<span style="color: #ff2600;">'testFolder/*'</span>],<br /><br />  multiCapabilities: [{<br />    <span style="color: #ff2600;">'browserName'</span>: <span style="color: #ff2600;">'chrome'</span>,<br />    <span style="color: #4f8f00;">// browser-specific tests</span><br />    specs: <span style="color: #ff2600;">'chromeTests/*'</span> <br />  }, {<br />    <span style="color: #ff2600;">'browserName'</span>: <span style="color: #ff2600;">'firefox'</span>,<br />    <span style="color: #4f8f00;">// run tests in parallel</span><br />    shardTestFiles: <span style="color: #0433ff;">true</span> <br />  }],<br /><br />  baseUrl: <span style="color: #ff2600;">'http://www.angularjs.org'</span>,<br />};</pre><br />4) Run the test: <br /><br />Start the test with the command: <br /><pre style="background: #f0f0f0; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;">protractor conf.js</pre><br />The test output should be: <br /><pre style="background: #f0f0f0; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;">1 test, 1 assertions, 0 failures</pre><br /><br />If you want to learn more, here’s a full tutorial that highlights all of Protractor’s features: <a href="http://angular.github.io/protractor/#/tutorial">http://angular.github.io/protractor/#/tutorial </a><br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/protractor-angular-testing-made-easy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>GTAC 2014 is this Week!</title>
		<link>https://googledata.org/google-testing/gtac-2014-is-this-week/</link>
		<comments>https://googledata.org/google-testing/gtac-2014-is-this-week/#comments</comments>
		<pubDate>Mon, 27 Oct 2014 18:26:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=b3c5e24cfb9f2949e703eed2ec89d3fa</guid>
		<description><![CDATA[by Anthony Vallone on behalf of the GTAC Committee  The eighth GTAC commences on Tuesday at the Google Kirkland office. You can find the latest details on the conference at our site, including speaker profiles. If you are watching remotely, we'll soon ...]]></description>
				<content:encoded><![CDATA[<i>by Anthony Vallone on behalf of the GTAC Committee  </i><br /><br />The eighth GTAC commences on Tuesday at the Google Kirkland office. You can find the latest details on the conference at our site, including <a href="https://developers.google.com/google-test-automation-conference/2014/speakers">speaker profiles</a>. <br /><br />If you are watching remotely, we'll soon be updating the <a href="https://developers.google.com/google-test-automation-conference/2014/stream">live stream page</a> with the stream link and a Google Moderator link for remote Q&amp;A. <br /><br />If you have been selected to attend or speak, be sure to note the <a href="https://developers.google.com/google-test-automation-conference/2014/travel">updated parking information</a>. Google visitors will use off-site parking and shuttles. <br /><br />We look forward to connecting with the greater testing community and sharing new advances and ideas. <br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/gtac-2014-is-this-week/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Testing on the Toilet: Writing Descriptive Test Names</title>
		<link>https://googledata.org/google-testing/testing-on-the-toilet-writing-descriptive-test-names/</link>
		<comments>https://googledata.org/google-testing/testing-on-the-toilet-writing-descriptive-test-names/#comments</comments>
		<pubDate>Thu, 16 Oct 2014 20:39:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=0ba0096d1178bf588125ce40628a334a</guid>
		<description><![CDATA[<i>by Andrew Trenk </i><br /><br /><i>This article was adapted from a <a href="http://googletesting.blogspot.com/2007/01/introducing-testing-on-toilet.html">Google Testing on the Toilet</a> (TotT) episode. You can download a <a href="https://docs.google.com/document/d/1UzvzMUkv0mpIFjrLqTcqvHFC5_1ycOCmrMVt-ubR2ec/edit?usp=sharing">printer-friendly version</a> of this TotT episode and post it in your office. </i><br /><br /><b><span>How long does it take you to figure out what behavior is being tested in the following code? </span></b><br /><br /><pre>@Test <span>public</span> <span>void</span> <b>isUserLockedOut_invalidLogin</b>() {<br /><b>authenticator</b>.authenticate(<b>username</b>, <b>invalidPassword</b>);<br />  assertFalse(<b>authenticator</b>.isUserLockedOut(<b>username</b>));<br /><br /><b>authenticator</b>.authenticate(<b>username</b>, <b>invalidPassword</b>);<br />  assertFalse(<b>authenticator</b>.isUserLockedOut(<b>username</b>));<br /><br /><b>authenticator</b>.authenticate(<b>username</b>, <b>invalidPassword</b>);<br />  assertTrue(<b>authenticator</b>.isUserLockedOut(<b>username</b>));<br />}</pre><br /><b><span>You probably had to read through every line of code</span></b> (maybe more than once) and understand what each line is doing. But <b><span>how long would it take you to figure out what behavior is being tested if the test had this name?</span></b><br /><br /><b><span>isUserLockedOut_lockOutUserAfterThreeInvalidLoginAttempts</span></b><br /><b><br /></b><b><span>You should now be able to understand what behavior is being tested by reading just the test name</span></b>, and you don&#8217;t even need to read through the test body. The test name in the above code sample hints at the scenario being tested (&#8220;invalidLogin&#8221;), but it doesn&#8217;t actually say what the expected outcome is supposed to be, so you had to read through the code to figure it out. <br /><br /><b><span>Putting both the scenario and the expected outcome in the test name has several other benefits: </span></b><br /><br />- <b><span>If you want to know all the possible behaviors a class has, all you need to do is read through the test names in its test class</span></b>, compared to spending minutes or hours digging through the test code or even the class itself trying to figure out its behavior. This can also be useful during code reviews since you can quickly tell if the tests cover all expected cases. <br /><br />- <b><span>By giving tests more explicit names, it forces you to split up testing different behaviors into separate tests</span></b>. Otherwise you may be tempted to dump assertions for different behaviors into one test, which over time can lead to tests that keep growing and become difficult to understand and maintain. <br /><br />- <b><span>The exact behavior being tested might not always be clear from the test code</span></b>. If the test name isn&#8217;t explicit about this, sometimes you might have to guess what the test is actually testing. <br /><br />- <b><span>You can easily tell if some functionality isn&#8217;t being tested</span></b>. If you don&#8217;t see a test name that describes the behavior you&#8217;re looking for, then you know the test doesn&#8217;t exist.  <br /><br />- <b><span>When a test fails, you can immediately see what functionality is broken without looking at the test&#8217;s source code</span></b>. <br /><br />There are several common patterns for structuring the name of a test (one example is to name tests like an English sentence with &#8220;should&#8221; in the name, e.g., <span>shouldLockOutUserAfterThreeInvalidLoginAttempts</span>). Whichever pattern you use, the same advice still applies: <span><b>Make sure test names contain both the scenario being tested and the expected outcome</b></span>.  <br /><br />Sometimes just specifying the name of the method under test may be enough, especially if the method is simple and has only a single behavior that is obvious from its name.  <br /><br />]]></description>
				<content:encoded><![CDATA[<i>by Andrew Trenk </i><br /><br /><i>This article was adapted from a <a href="http://googletesting.blogspot.com/2007/01/introducing-testing-on-toilet.html">Google Testing on the Toilet</a> (TotT) episode. You can download a <a href="https://docs.google.com/document/d/1UzvzMUkv0mpIFjrLqTcqvHFC5_1ycOCmrMVt-ubR2ec/edit?usp=sharing">printer-friendly version</a> of this TotT episode and post it in your office. </i><br /><br /><b><span style="color: #990000;">How long does it take you to figure out what behavior is being tested in the following code? </span></b><br /><br /><pre style="background: #fff2cc; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;">@Test <span style="color: #0433ff;">public</span> <span style="color: #0433ff;">void</span> <b>isUserLockedOut_invalidLogin</b>() {<br />  <b>authenticator</b>.authenticate(<b>username</b>, <b>invalidPassword</b>);<br />  assertFalse(<b>authenticator</b>.isUserLockedOut(<b>username</b>));<br /><br />  <b>authenticator</b>.authenticate(<b>username</b>, <b>invalidPassword</b>);<br />  assertFalse(<b>authenticator</b>.isUserLockedOut(<b>username</b>));<br /><br />  <b>authenticator</b>.authenticate(<b>username</b>, <b>invalidPassword</b>);<br />  assertTrue(<b>authenticator</b>.isUserLockedOut(<b>username</b>));<br />}</pre><br /><b><span style="color: #990000;">You probably had to read through every line of code</span></b> (maybe more than once) and understand what each line is doing. But <b><span style="color: #990000;">how long would it take you to figure out what behavior is being tested if the test had this name?</span></b><br /><br /><b><span style="font-family: Courier New, Courier, monospace;">isUserLockedOut_lockOutUserAfterThreeInvalidLoginAttempts</span></b><br /><b><br /></b><b><span style="color: #990000;">You should now be able to understand what behavior is being tested by reading just the test name</span></b>, and you don’t even need to read through the test body. The test name in the above code sample hints at the scenario being tested (“invalidLogin”), but it doesn’t actually say what the expected outcome is supposed to be, so you had to read through the code to figure it out. <br /><br /><b><span style="color: #990000;">Putting both the scenario and the expected outcome in the test name has several other benefits: </span></b><br /><br />- <b><span style="color: #990000;">If you want to know all the possible behaviors a class has, all you need to do is read through the test names in its test class</span></b>, compared to spending minutes or hours digging through the test code or even the class itself trying to figure out its behavior. This can also be useful during code reviews since you can quickly tell if the tests cover all expected cases. <br /><br />- <b><span style="color: #990000;">By giving tests more explicit names, it forces you to split up testing different behaviors into separate tests</span></b>. Otherwise you may be tempted to dump assertions for different behaviors into one test, which over time can lead to tests that keep growing and become difficult to understand and maintain. <br /><br />- <b><span style="color: #990000;">The exact behavior being tested might not always be clear from the test code</span></b>. If the test name isn’t explicit about this, sometimes you might have to guess what the test is actually testing. <br /><br />- <b><span style="color: #990000;">You can easily tell if some functionality isn’t being tested</span></b>. If you don’t see a test name that describes the behavior you’re looking for, then you know the test doesn’t exist.  <br /><br />- <b><span style="color: #990000;">When a test fails, you can immediately see what functionality is broken without looking at the test’s source code</span></b>. <br /><br />There are several common patterns for structuring the name of a test (one example is to name tests like an English sentence with “should” in the name, e.g., <span style="font-family: Courier New, Courier, monospace;">shouldLockOutUserAfterThreeInvalidLoginAttempts</span>). Whichever pattern you use, the same advice still applies: <span style="color: #990000;"><b>Make sure test names contain both the scenario being tested and the expected outcome</b></span>.  <br /><br />Sometimes just specifying the name of the method under test may be enough, especially if the method is simple and has only a single behavior that is obvious from its name.  <br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/testing-on-the-toilet-writing-descriptive-test-names/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Announcing the GTAC 2014 Agenda</title>
		<link>https://googledata.org/google-testing/announcing-the-gtac-2014-agenda/</link>
		<comments>https://googledata.org/google-testing/announcing-the-gtac-2014-agenda/#comments</comments>
		<pubDate>Wed, 01 Oct 2014 00:36:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=e1f9e0b7793151892e50873d9142e1d8</guid>
		<description><![CDATA[<i>by Anthony Vallone on behalf of the GTAC Committee  </i><br /><br />We have completed selection and confirmation of all speakers and attendees for GTAC 2014. You can find the detailed agenda at: <br />&#160;&#160;<a href="http://developers.google.com/gtac/2014/schedule">developers.google.com/gtac/2014/schedule</a><br /><br />Thank you to all who submitted proposals! It was very hard to make selections from so many fantastic submissions. <br /><br />There was a tremendous amount of interest in GTAC this year with over 1,500 applicants (up from 533 last year) and 194 of those for speaking (up from 88 last year). Unfortunately, our venue only seats 250. However, don&#8217;t despair if you did not receive an invitation. Just like last year, anyone can join us via <a href="https://developers.google.com/google-test-automation-conference/2014/stream">YouTube live streaming</a>. We&#8217;ll also be setting up Google Moderator, so remote attendees can get involved in Q&#38;A after each talk. Information about live streaming, Moderator, and other details will be posted on the GTAC site soon and announced here. <br /><br />]]></description>
				<content:encoded><![CDATA[<i>by Anthony Vallone on behalf of the GTAC Committee  </i><br /><br />We have completed selection and confirmation of all speakers and attendees for GTAC 2014. You can find the detailed agenda at: <br />&nbsp;&nbsp;<a href="http://developers.google.com/gtac/2014/schedule">developers.google.com/gtac/2014/schedule</a><br /><br />Thank you to all who submitted proposals! It was very hard to make selections from so many fantastic submissions. <br /><br />There was a tremendous amount of interest in GTAC this year with over 1,500 applicants (up from 533 last year) and 194 of those for speaking (up from 88 last year). Unfortunately, our venue only seats 250. However, don’t despair if you did not receive an invitation. Just like last year, anyone can join us via <a href="https://developers.google.com/google-test-automation-conference/2014/stream">YouTube live streaming</a>. We’ll also be setting up Google Moderator, so remote attendees can get involved in Q&amp;A after each talk. Information about live streaming, Moderator, and other details will be posted on the GTAC site soon and announced here. <br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/announcing-the-gtac-2014-agenda/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Chrome &#8211; Firefox WebRTC Interop Test &#8211; Pt 2</title>
		<link>https://googledata.org/google-testing/chrome-firefox-webrtc-interop-test-pt-2/</link>
		<comments>https://googledata.org/google-testing/chrome-firefox-webrtc-interop-test-pt-2/#comments</comments>
		<pubDate>Tue, 09 Sep 2014 20:05:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=dc693df5a565e711d4e34e188f2d176c</guid>
		<description><![CDATA[<i>by Patrik H&#246;glund </i><br /><i><br /></i><i>This is the second in a series of articles about Chrome&#8217;s WebRTC Interop Test. <a href="http://googletesting.blogspot.com/2014/08/chrome-firefox-webrtc-interop-test-pt-1.html">See the first</a>.</i><br /><br />In the previous blog post we managed to write an automated test which got a WebRTC call between Firefox and Chrome to run. But how do we verify that the call actually worked?<br /><br /><h3>Verifying the Call</h3>Now we can launch the two browsers, but how do we figure out the whether the call actually worked? If you try opening two <a href="http://apprtc.appspot.com/">apprtc.appspot.com</a> tabs in the same room, you will notice the video feeds flip over using a CSS transform, your local video is relegated to a small frame and a new big video feed with the remote video shows up. For the first version of the test, I just looked at the page in the Chrome debugger and looked for some reliable signal. As it turns out, the <span><b>remoteVideo.style.opacity</b></span> property will go from 0 to 1 when the call goes up and from 1 to 0 when it goes down. Since we can execute arbitrary JavaScript in the Chrome tab from the test, we can simply implement the check like this: <br /><br /><pre><span>bool</span> WaitForCallToComeUp(content::WebContents* tab_contents) {<br /><span>// Apprtc will set remoteVideo.style.opacity to 1 when the call comes up.</span><br />  std::<span>string</span> javascript =<br /><span>"window.domAutomationController.send(remoteVideo.style.opacity)"</span>;<br /><span>return</span> test::PollingWaitUntil(javascript, <span>"1"</span>, tab_contents);<br />}<br /></pre><br /><h3>Verifying Video is Playing</h3>So getting a call up is good, but what if there is a bug where Firefox and Chrome cannot send correct video streams to each other? To check that, we needed to step up our game a bit. We decided to use our <a href="https://code.google.com/p/chromium/codesearch#chromium/src/chrome/test/data/webrtc/video_detector.js&#38;q=video_dete&#38;sq=package:chromium&#38;l=1">existing video detector</a>, which looks at a video element and determines if the pixels are changing. This is a very basic check, but it&#8217;s better than nothing. To do this, we simply evaluate the .js file&#8217;s JavaScript in the context of the Chrome tab, making the functions in the file available to us. The implementation then becomes <br /><br /><pre><span>bool</span> DetectRemoteVideoPlaying(content::WebContents* tab_contents) {<br /><span>if</span> (!EvalInJavascriptFile(tab_contents, GetSourceDir().Append(<br />      FILE_PATH_LITERAL(<br /><span>"chrome/test/data/webrtc/test_functions.js"</span>))))<br /><span>return</span> <span>false</span>;<br /><span>if</span> (!EvalInJavascriptFile(tab_contents, GetSourceDir().Append(<br />      FILE_PATH_LITERAL(<br /><span>"chrome/test/data/webrtc/video_detector.js"</span>))))<br /><span>return</span> <span>false</span>;<br /><br /><span>// The remote video tag is called remoteVideo in the AppRTC code.</span><br />  StartDetectingVideo(tab_contents, <span>"remoteVideo"</span>);<br />  WaitForVideoToPlay(tab_contents);<br /><span>return</span> <span>true</span>;<br />}</pre><br />where <span><b>StartDetectingVideo</b></span> and <span><b>WaitForVideoToPlay</b></span> call the corresponding JavaScript methods in <a href="https://code.google.com/p/chromium/codesearch#chromium/src/chrome/test/data/webrtc/video_detector.js&#38;q=video_dete&#38;sq=package:chromium&#38;l=61">video_detector.js</a>. If the video feed is frozen and unchanging, the test will time out and fail.<br /><br /><h3>What to Send in the Call</h3>Now we can get a call up between the browsers and detect if video is playing. But what video should we send? For chrome, we have a convenient <span><b>--use-fake-device-for-media-stream</b></span> flag that will make Chrome pretend there&#8217;s a webcam and present a generated video feed (which is a spinning green ball with a timestamp). This turned out to be useful since Firefox and Chrome cannot acquire the same camera at the same time, so if we didn&#8217;t use the fake device we would have two webcams plugged into the bots executing the tests! <br /><br />Bots running in Chrome&#8217;s <a href="http://build.chromium.org/">regular test infrastructure</a> do not have either software or hardware webcams plugged into them, so this test must run on bots with webcams for Firefox to be able to acquire a camera. Fortunately, we have that in the <a href="http://build.chromium.org/p/chromium.webrtc/waterfall">WebRTC waterfalls</a> in order to test that we can actually acquire hardware webcams on all platforms. We also added a check to just succeed the test when there&#8217;s no real webcam on the system since we don&#8217;t want it to fail when a dev runs it on a machine without a webcam:  <br /><br /><pre><span>if</span> (!HasWebcamOnSystem())<br /><span>return</span>;<br /></pre><br />It would of course be better if Firefox had a similar fake device, but to my knowledge it doesn&#8217;t.<br /><br /><h3>Downloading all Code and Components&#160;</h3>Now we have all we need to run the test and have it verify something useful. We just have the hard part left: how do we actually download all the resources we need to run this test? Recall that this is actually a three-way integration test between Chrome, Firefox and AppRTC, which require the following:<br /><br /><ul><li>The AppEngine SDK in order to bring up the local AppRTC instance,&#160;</li><li>The AppRTC code itself,&#160;</li><li>Chrome (already present in the checkout), and&#160;</li><li>Firefox nightly.</li></ul><br />While developing the test, I initially just hand-downloaded these and installed and hard-coded the paths. This is a very bad idea in the long run. Recall that the Chromium infrastructure is comprised of <a href="http://build.chromium.org/">thousands and thousands of machines</a>, and while this test will only run on perhaps 5 at a time due to its webcam requirements, we don&#8217;t want manual maintenance work whenever we replace a machine. And for that matter, we definitely don&#8217;t want to download a new Firefox by hand every night and put it on the right location on the bots! So how do we automate this? <br /><br /><b>Downloading the AppEngine SDK</b><br />First, let&#8217;s start with the easy part. We don&#8217;t really care if the AppEngine SDK is up-to-date, so a relatively stale version is fine. We could have the test download it from the <a href="https://developers.google.com/appengine/downloads">authoritative source</a>, but that&#8217;s a bad idea for a couple reasons. First, it updates outside our control. Second, there could be anti-robot measures on the page. Third, the download will likely be unreliable and fail the test occasionally. <br /><br />The way we solved this was to upload a copy of the SDK to a <a href="https://cloud.google.com/products/cloud-storage/?utm_source=google&#38;utm_medium=cpc&#38;utm_campaign=cloudstorage-search">Google storage</a> bucket under our control and download it using the <a href="http://dev.chromium.org/developers/how-tos/depottools">depot_tools</a> script <span><b>download_from_google_storage.py</b></span>. This is a lot more reliable than an external website and will not download the SDK if we already have the right version on the bot. <br /><br /><b>Downloading the AppRTC Code</b><br />This code is on GitHub. Experience has shown that git clone commands run against GitHub will fail every now and then, and fail the test. We could either write some retry mechanism, but we have found it&#8217;s better to simply mirror the git repository in Chromium&#8217;s internal mirrors, which are closer to our bots and thereby more reliable from our perspective. The pull is done by a <a href="http://chromegw/viewvc/chrome/trunk/deps/third_party/webrtc/webrtc.DEPS/DEPS?revision=262390&#38;view=markup">Chromium DEPS file</a> (which is Chromium&#8217;s dependency provisioning framework). <br /><br /><b>Downloading Firefox</b><br />It turns out that Firefox supplies handy libraries for this task. We&#8217;re using mozdownload <a href="http://chromegw/viewvc/chrome/trunk/deps/third_party/webrtc/webrtc.DEPS/download_firefox_nightly.py?revision=241269&#38;view=markup">in this script</a> in order to download the Firefox nightly build. Unfortunately this <a href="https://code.google.com/p/chromium/issues/detail?id=360516">fails every now and then</a> so we would like to have some retry mechanism, or we could write some mechanism to &#8220;mirror&#8221; the Firefox nightly build in some location we control.<br /><br /><h3>Putting it Together</h3>With that, we have everything we need to deploy the test. You can see the <a href="https://code.google.com/p/chromium/codesearch#chromium/src/chrome/browser/media/chrome_webrtc_apprtc_browsertest.cc&#38;q=chrome_webrtc_app&#38;sq=package:chromium&#38;l=297">final code here</a>.  <br /><br />The provisioning code above was put into a separate &#8220;<a href="http://chromegw/viewvc/chrome/trunk/deps/third_party/webrtc/webrtc.DEPS/">.gclient solution</a>&#8221; so that regular Chrome devs and bots are not burdened with downloading hundreds of megs of SDKs and code that they will not use. When this test runs, you will first see a Chrome browser pop up, which will ensure the local apprtc instance is up. Then a Firefox browser will pop up. They will each acquire the fake device and real camera, respectively, and after a short delay the AppRTC call will come up, proving that video interop is working. <br /><br />This is a complicated and expensive test, but we believe it is worth it to keep the main interop case under automation this way, especially as the spec evolves and the browsers are in varying states of implementation. <br /><br />Future Work<br /><br /><ul><li>Also run on Windows/Mac.&#160;</li><li>Also test Opera.&#160;</li><li>Interop between Chrome/Firefox mobile and desktop browsers.&#160;</li><li>Also ensure audio is playing.&#160;</li><li>Measure bandwidth stats, video quality, etc.</li></ul><br /><br />]]></description>
				<content:encoded><![CDATA[<i>by Patrik Höglund </i><br /><i><br /></i><i>This is the second in a series of articles about Chrome’s WebRTC Interop Test. <a href="http://googletesting.blogspot.com/2014/08/chrome-firefox-webrtc-interop-test-pt-1.html">See the first</a>.</i><br /><br />In the previous blog post we managed to write an automated test which got a WebRTC call between Firefox and Chrome to run. But how do we verify that the call actually worked?<br /><br /><h3>Verifying the Call</h3>Now we can launch the two browsers, but how do we figure out the whether the call actually worked? If you try opening two <a href="http://apprtc.appspot.com/">apprtc.appspot.com</a> tabs in the same room, you will notice the video feeds flip over using a CSS transform, your local video is relegated to a small frame and a new big video feed with the remote video shows up. For the first version of the test, I just looked at the page in the Chrome debugger and looked for some reliable signal. As it turns out, the <span style="color: #6aa84f; font-family: Courier New, Courier, monospace;"><b>remoteVideo.style.opacity</b></span> property will go from 0 to 1 when the call goes up and from 1 to 0 when it goes down. Since we can execute arbitrary JavaScript in the Chrome tab from the test, we can simply implement the check like this: <br /><br /><pre style="background: #f0f0f0; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;"><span style="color: #0433ff;">bool</span> WaitForCallToComeUp(content::WebContents* tab_contents) {<br />  <span style="color: #4f8f00;">// Apprtc will set remoteVideo.style.opacity to 1 when the call comes up.</span><br />  std::<span style="color: #0433ff;">string</span> javascript =<br />      <span style="color: #ff2600;">"window.domAutomationController.send(remoteVideo.style.opacity)"</span>;<br />  <span style="color: #0433ff;">return</span> test::PollingWaitUntil(javascript, <span style="color: #ff2600;">"1"</span>, tab_contents);<br />}<br /></pre><br /><h3>Verifying Video is Playing</h3>So getting a call up is good, but what if there is a bug where Firefox and Chrome cannot send correct video streams to each other? To check that, we needed to step up our game a bit. We decided to use our <a href="https://code.google.com/p/chromium/codesearch#chromium/src/chrome/test/data/webrtc/video_detector.js&amp;q=video_dete&amp;sq=package:chromium&amp;l=1">existing video detector</a>, which looks at a video element and determines if the pixels are changing. This is a very basic check, but it’s better than nothing. To do this, we simply evaluate the .js file’s JavaScript in the context of the Chrome tab, making the functions in the file available to us. The implementation then becomes <br /><br /><pre style="background: #f0f0f0; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;"><span style="color: #0433ff;">bool</span> DetectRemoteVideoPlaying(content::WebContents* tab_contents) {<br />  <span style="color: #0433ff;">if</span> (!EvalInJavascriptFile(tab_contents, GetSourceDir().Append(<br />      FILE_PATH_LITERAL(<br />          <span style="color: #ff2600;">"chrome/test/data/webrtc/test_functions.js"</span>))))<br />    <span style="color: #0433ff;">return</span> <span style="color: #0433ff;">false</span>;<br />  <span style="color: #0433ff;">if</span> (!EvalInJavascriptFile(tab_contents, GetSourceDir().Append(<br />      FILE_PATH_LITERAL(<br />          <span style="color: #ff2600;">"chrome/test/data/webrtc/video_detector.js"</span>))))<br />    <span style="color: #0433ff;">return</span> <span style="color: #0433ff;">false</span>;<br /><br />  <span style="color: #4f8f00;">// The remote video tag is called remoteVideo in the AppRTC code.</span><br />  StartDetectingVideo(tab_contents, <span style="color: #ff2600;">"remoteVideo"</span>);<br />  WaitForVideoToPlay(tab_contents);<br />  <span style="color: #0433ff;">return</span> <span style="color: #0433ff;">true</span>;<br />}</pre><br />where <span style="color: #6aa84f; font-family: Courier New, Courier, monospace;"><b>StartDetectingVideo</b></span> and <span style="color: #6aa84f; font-family: Courier New, Courier, monospace;"><b>WaitForVideoToPlay</b></span> call the corresponding JavaScript methods in <a href="https://code.google.com/p/chromium/codesearch#chromium/src/chrome/test/data/webrtc/video_detector.js&amp;q=video_dete&amp;sq=package:chromium&amp;l=61">video_detector.js</a>. If the video feed is frozen and unchanging, the test will time out and fail.<br /><br /><h3>What to Send in the Call</h3>Now we can get a call up between the browsers and detect if video is playing. But what video should we send? For chrome, we have a convenient <span style="color: #6aa84f; font-family: Courier New, Courier, monospace;"><b>--use-fake-device-for-media-stream</b></span> flag that will make Chrome pretend there’s a webcam and present a generated video feed (which is a spinning green ball with a timestamp). This turned out to be useful since Firefox and Chrome cannot acquire the same camera at the same time, so if we didn’t use the fake device we would have two webcams plugged into the bots executing the tests! <br /><br />Bots running in Chrome’s <a href="http://build.chromium.org/">regular test infrastructure</a> do not have either software or hardware webcams plugged into them, so this test must run on bots with webcams for Firefox to be able to acquire a camera. Fortunately, we have that in the <a href="http://build.chromium.org/p/chromium.webrtc/waterfall">WebRTC waterfalls</a> in order to test that we can actually acquire hardware webcams on all platforms. We also added a check to just succeed the test when there’s no real webcam on the system since we don’t want it to fail when a dev runs it on a machine without a webcam:  <br /><br /><pre style="background: #f0f0f0; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;"><span style="color: #0433ff;">if</span> (!HasWebcamOnSystem())<br />  <span style="color: #0433ff;">return</span>;<br /></pre><br />It would of course be better if Firefox had a similar fake device, but to my knowledge it doesn’t.<br /><br /><h3>Downloading all Code and Components&nbsp;</h3>Now we have all we need to run the test and have it verify something useful. We just have the hard part left: how do we actually download all the resources we need to run this test? Recall that this is actually a three-way integration test between Chrome, Firefox and AppRTC, which require the following:<br /><br /><ul style="line-height: 1.0em; margin-bottom: 0px; margin-top: 0px; padding-bottom: 0px; padding-top: 0px;"><li>The AppEngine SDK in order to bring up the local AppRTC instance,&nbsp;</li><li>The AppRTC code itself,&nbsp;</li><li>Chrome (already present in the checkout), and&nbsp;</li><li>Firefox nightly.</li></ul><br />While developing the test, I initially just hand-downloaded these and installed and hard-coded the paths. This is a very bad idea in the long run. Recall that the Chromium infrastructure is comprised of <a href="http://build.chromium.org/">thousands and thousands of machines</a>, and while this test will only run on perhaps 5 at a time due to its webcam requirements, we don’t want manual maintenance work whenever we replace a machine. And for that matter, we definitely don’t want to download a new Firefox by hand every night and put it on the right location on the bots! So how do we automate this? <br /><br /><b>Downloading the AppEngine SDK</b><br />First, let’s start with the easy part. We don’t really care if the AppEngine SDK is up-to-date, so a relatively stale version is fine. We could have the test download it from the <a href="https://developers.google.com/appengine/downloads">authoritative source</a>, but that’s a bad idea for a couple reasons. First, it updates outside our control. Second, there could be anti-robot measures on the page. Third, the download will likely be unreliable and fail the test occasionally. <br /><br />The way we solved this was to upload a copy of the SDK to a <a href="https://cloud.google.com/products/cloud-storage/?utm_source=google&amp;utm_medium=cpc&amp;utm_campaign=cloudstorage-search">Google storage</a> bucket under our control and download it using the <a href="http://dev.chromium.org/developers/how-tos/depottools">depot_tools</a> script <span style="color: #6aa84f; font-family: Courier New, Courier, monospace;"><b>download_from_google_storage.py</b></span>. This is a lot more reliable than an external website and will not download the SDK if we already have the right version on the bot. <br /><br /><b>Downloading the AppRTC Code</b><br />This code is on GitHub. Experience has shown that git clone commands run against GitHub will fail every now and then, and fail the test. We could either write some retry mechanism, but we have found it’s better to simply mirror the git repository in Chromium’s internal mirrors, which are closer to our bots and thereby more reliable from our perspective. The pull is done by a <a href="http://chromegw/viewvc/chrome/trunk/deps/third_party/webrtc/webrtc.DEPS/DEPS?revision=262390&amp;view=markup">Chromium DEPS file</a> (which is Chromium’s dependency provisioning framework). <br /><br /><b>Downloading Firefox</b><br />It turns out that Firefox supplies handy libraries for this task. We’re using mozdownload <a href="http://chromegw/viewvc/chrome/trunk/deps/third_party/webrtc/webrtc.DEPS/download_firefox_nightly.py?revision=241269&amp;view=markup">in this script</a> in order to download the Firefox nightly build. Unfortunately this <a href="https://code.google.com/p/chromium/issues/detail?id=360516">fails every now and then</a> so we would like to have some retry mechanism, or we could write some mechanism to “mirror” the Firefox nightly build in some location we control.<br /><br /><h3>Putting it Together</h3>With that, we have everything we need to deploy the test. You can see the <a href="https://code.google.com/p/chromium/codesearch#chromium/src/chrome/browser/media/chrome_webrtc_apprtc_browsertest.cc&amp;q=chrome_webrtc_app&amp;sq=package:chromium&amp;l=297">final code here</a>.  <br /><br />The provisioning code above was put into a separate “<a href="http://chromegw/viewvc/chrome/trunk/deps/third_party/webrtc/webrtc.DEPS/">.gclient solution</a>” so that regular Chrome devs and bots are not burdened with downloading hundreds of megs of SDKs and code that they will not use. When this test runs, you will first see a Chrome browser pop up, which will ensure the local apprtc instance is up. Then a Firefox browser will pop up. They will each acquire the fake device and real camera, respectively, and after a short delay the AppRTC call will come up, proving that video interop is working. <br /><br />This is a complicated and expensive test, but we believe it is worth it to keep the main interop case under automation this way, especially as the spec evolves and the browsers are in varying states of implementation. <br /><br />Future Work<br /><br /><ul style="line-height: 1.0em; margin-bottom: 0px; margin-top: 0px; padding-bottom: 0px; padding-top: 0px;"><li>Also run on Windows/Mac.&nbsp;</li><li>Also test Opera.&nbsp;</li><li>Interop between Chrome/Firefox mobile and desktop browsers.&nbsp;</li><li>Also ensure audio is playing.&nbsp;</li><li>Measure bandwidth stats, video quality, etc.</li></ul><br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/chrome-firefox-webrtc-interop-test-pt-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Chrome &#8211; Firefox WebRTC Interop Test &#8211; Pt 1</title>
		<link>https://googledata.org/google-testing/chrome-firefox-webrtc-interop-test-pt-1/</link>
		<comments>https://googledata.org/google-testing/chrome-firefox-webrtc-interop-test-pt-1/#comments</comments>
		<pubDate>Tue, 26 Aug 2014 21:05:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=02263ce11a5c1f2094ff18d8d7dd2203</guid>
		<description><![CDATA[<i>by Patrik H&#246;glund </i><br /><br /><a href="http://www.webrtc.org/">WebRTC</a> enables real time peer-to-peer video and voice transfer in the browser, making it possible to build, among other things, a <a href="https://apprtc.appspot.com/">working video chat</a> with a <a href="https://github.com/GoogleChrome/webrtc/tree/master/samples/web/content/apprtc">small amount of Python and JavaScript</a>. As a web standard, it has several unusual properties which makes it hard to test. A regular web standard generally accepts HTML text and yields a bitmap as output (what you see in the browser). For WebRTC, we have real-time RTP media streams on one side being sent to another WebRTC-enabled endpoint. These RTP packets have been jumping across NAT, through firewalls and perhaps through TURN servers to deliver hopefully stutter-free and low latency media. <br /><br />WebRTC is probably the only web standard in which we need to test direct communication between Chrome and other browsers. Remember, WebRTC builds on peer-to-peer technology, which means we talk directly between browsers rather than through a server. Chrome, Firefox and Opera have announced support for WebRTC so far. To test interoperability, we set out to build an automated test to ensure that Chrome and Firefox can get a call up. This article describes how we implemented such a test and the tradeoffs we made along the way.<br /><br /><h3>Calling in WebRTC </h3>Setting up a WebRTC call requires passing  SDP blobs over a signaling connection. These blobs contain information on the capabilities of the endpoint, such as what media formats it supports and what preferences it has (for instance, perhaps the endpoint has VP8 decoding hardware, which means the endpoint will handle VP8 more efficiently than, say, H.264). By sending these blobs the endpoints can agree on what media format they will be sending between themselves and how to traverse the network between them. Once that is done, the browsers will talk directly to each other, and nothing gets sent over the signaling connection.<br /><br /><div><a href="http://4.bp.blogspot.com/-A6zQCufOABs/U_zvIGck2gI/AAAAAAAAAG0/FlqBUQ8h_XY/s1600/image00.png"><img border="0" src="http://4.bp.blogspot.com/-A6zQCufOABs/U_zvIGck2gI/AAAAAAAAAG0/FlqBUQ8h_XY/s1600/image00.png" width="500"></a></div><div><i>Figure 1. Signaling and media connections.</i></div><br />How these blobs are sent is up to the application. Usually the browsers connect to some server which mediates the connection between the browsers, for instance by using a contact list or a room number. The <a href="https://apprtc.appspot.com/">AppRTC reference application</a> uses room numbers to pair up browsers and sends the SDP blobs from the browsers through the AppRTC server.<br /><br /><h3>Test Design</h3>Instead of designing a new signaling solution from scratch, we chose to use the AppRTC application we already had. This has the additional benefit of testing the AppRTC code, which we are also maintaining. We could also have used the small <a href="https://code.google.com/p/chromium/codesearch#chromium/src/third_party/libjingle/libjingle.gyp&#38;q=peerconnection_server&#38;sq=package:chromium&#38;type=cs&#38;l=289">peerconnection_server</a> binary and some JavaScript, which would give us additional flexibility in what to test. We chose to go with AppRTC since it effectively implements the signaling for us, leading to much less test code. <br /><br />We assumed we would be able to get hold of the latest nightly Firefox and be able to launch that with a given URL. For the Chrome side, we assumed we would be running in a browser test, i.e. on a complete Chrome with some test scaffolding around it. For the first sketch of the test, we imagined just connecting the browsers to the live <a href="http://apprtc.appspot.com/">apprtc.appspot.com</a> with some random room number. If the call got established, we would be able to look at the remote video feed on the Chrome side and verify that video was playing (for instance using the <a href="http://googlechrome.github.io/webrtc/samples/web/content/getusermedia-canvas">video+canvas grab trick</a>). Furthermore, we could verify that audio was playing, for instance by using <a href="http://googlechrome.github.io/webrtc/samples/web/content/getusermedia-volume">WebRTC getStats</a> to measure the audio track energy level. <br /><br /><div><a href="http://2.bp.blogspot.com/-KLMJbuz7uGg/U_zvNllz-vI/AAAAAAAAAG8/JJK4j05TQOI/s1600/image01.png"><img border="0" src="http://2.bp.blogspot.com/-KLMJbuz7uGg/U_zvNllz-vI/AAAAAAAAAG8/JJK4j05TQOI/s1600/image01.png" width="500"></a></div><div><i>Figure 2. Basic test design.</i></div><br />However, since we like tests to be <a href="http://googletesting.blogspot.se/2012/10/hermetic-servers.html">hermetic</a>, this isn&#8217;t a good design. I can see several problems. For example, if the network between us and AppRTC is unreliable. Also, what if someone has occupied myroomid? If that were the case, the test would fail and we would be none the wiser. So to make this thing work, we would have to find some way to bring up the AppRTC instance on localhost to make our test hermetic.<br /><br /><h3>Bringing up AppRTC on localhost</h3>AppRTC is a <a href="https://developers.google.com/appengine/">Google App Engine application</a>. As this <a href="https://developers.google.com/appengine/docs/python/gettingstartedpython27/helloworld">hello world example</a> demonstrates, one can test applications locally with<br /><pre>google_appengine/dev_appserver.py apprtc_code/</pre><br />So why not just call this from our test? It turns out we need to solve some complicated problems first, like how to ensure the AppEngine SDK and the AppRTC code is actually available on the executing machine, but we&#8217;ll get to that later. Let&#8217;s assume for now that stuff is just available. We can now write the browser test code to launch the local instance:<br /><pre><span>bool</span> LaunchApprtcInstanceOnLocalhost() <br /><span>// ... Figure out locations of SDK and apprtc code ...</span><br />  CommandLine command_line(CommandLine::NO_PROGRAM);<br />  EXPECT_TRUE(GetPythonCommand(&#38;command_line));<br /><br />  command_line.AppendArgPath(appengine_dev_appserver);<br />  command_line.AppendArgPath(apprtc_dir);<br />  command_line.AppendArg(<span>"--port=9999"</span>);<br />  command_line.AppendArg(<span>"--admin_port=9998"</span>);<br />  command_line.AppendArg(<span>"--skip_sdk_update_check"</span>);<br /><br />  VLOG(1) &#60;&#60; <span>"Running "</span> &#60;&#60; command_line.GetCommandLineString();<br /><span>return</span> base::LaunchProcess(command_line, base::LaunchOptions(),<br />                             &#38;dev_appserver_);<br />}<br /></pre><br />That&#8217;s pretty straightforward <a href="http://googletesting.blogspot.com/#foot1"><sup>[1]</sup></a>.<br /><br /><h3>Figuring out Whether the Local Server is Up&#160;</h3>Then we ran into a very typical test problem. So we have the code to get the server up, and launching the two browsers to connect to <span><b>http://localhost:9999?r=some_room</b></span> is easy. But how do we know when to connect? When I first ran the test, it would work sometimes and sometimes not depending on if the server had time to get up. <br /><br />It&#8217;s tempting in these situations to just add a sleep to give the server time to get up. Don&#8217;t do that. That will result in a test that is flaky and/or slow. In these situations we need to identify what we&#8217;re really waiting for. We could probably monitor the stdout of the <b><span>dev_appserver.py</span></b> and look for some message that says &#8220;Server is up!&#8221; or equivalent. However, we&#8217;re really waiting for the server to be able to serve web pages, and since we have two browsers that are really good at connecting to servers, why not use them? Consider this code.<br /><pre><span>bool</span> LocalApprtcInstanceIsUp() {<br /><span>// Load the admin page and see if we manage to load it right.</span><br />  ui_test_utils::NavigateToURL(browser(), GURL(<span>"localhost:9998"</span>));<br />  content::WebContents* tab_contents =<br />      browser()-&#62;tab_strip_model()-&#62;GetActiveWebContents();<br />  std::<span>string</span> javascript =<br /><span>"window.domAutomationController.send(document.title)"</span>;<br />  std::<span>string</span> result;<br /><span>if</span> (!content::ExecuteScriptAndExtractString(tab_contents, <br />                                              javascript,<br />                                              &#38;result))<br /><span>return</span> <span>false</span>;<br /><br /><span>return</span> result == kTitlePageOfAppEngineAdminPage;<br />}<br /></pre><br />Here we ask Chrome to load the AppEngine admin page for the local server (we set the admin port to <span><b>9998</b></span> earlier, remember?) and ask it what its title is. If that title is &#8220;Instances&#8221;, the admin page has been displayed, and the server must be up. If the server isn&#8217;t up, Chrome will fail to load the page and the title will be something like &#8220;<span><b>localhost:9999</b></span> is not available&#8221;. <br /><br />Then, we can just do this from the test:<br /><pre><span>while</span> (!LocalApprtcInstanceIsUp())<br />  VLOG(1) &#60;&#60; <span>"Waiting for AppRTC to come up..."</span>;<br /></pre><br />If the server never comes up, for whatever reason, the test will just time out in that loop. If it comes up we can safely proceed with the rest of test.<br /><br /><h3>Launching the Browsers&#160;</h3>A browser window launches itself as a part of every Chromium browser test. It&#8217;s also easy for the test to control the command line switches the browser will run under. <br /><br />We have less control over the Firefox browser since it is the &#8220;foreign&#8221; browser in this test, but we can still pass command-line options to it when we invoke the Firefox process. To make this easier, Mozilla provides a Python library called mozrunner. Using that we can set up a <a href="http://chromegw/viewvc/chrome/trunk/deps/third_party/webrtc/webrtc.DEPS/run_firefox_webrtc.py?revision=240895&#38;view=markup">launcher python script</a> we can invoke from the test:<br /><pre><span>from</span> mozprofile <span>import</span> profile<br /><span>from</span> mozrunner <span>import</span> runner<br /><br />WEBRTC_PREFERENCES = {<br /><span>'media.navigator.permission.disabled'</span>: True,<br />}<br /><br /><span>def</span> main():<br /><span># Set up flags, handle SIGTERM, etc</span><br /><span># ...</span><br />  firefox_profile = <br />      profile.FirefoxProfile(preferences=WEBRTC_PREFERENCES)<br />  firefox_runner = runner.FirefoxRunner(<br />      profile=firefox_profile, binary=options.binary, <br />      cmdargs=[options.webpage])<br /><br />  firefox_runner.start()</pre><br />Notice that we need to pass special preferences to make Firefox accept the getUserMedia prompt. Otherwise, the test would get stuck on the prompt and we would be unable to set up a call. Alternatively, we could employ some kind of clickbot to click &#8220;Allow&#8221; on the prompt when it pops up, but that is way harder to set up. <br /><br />Without going into too much detail, the code for launching the browsers becomes<br /><pre>GURL room_url = <br />    GURL(base::StringPrintf(<span>"http://localhost:9999?r=room_%d"</span>,<br />                            base::RandInt(0, 65536)));<br />content::WebContents* chrome_tab = <br />    OpenPageAndAcceptUserMedia(room_url);<br />ASSERT_TRUE(LaunchFirefoxWithUrl(room_url));</pre><br />Where LaunchFirefoxWithUrl essentially runs this:<br /><pre>run_firefox_webrtc.py --binary /path/to/firefox --webpage http:<span>//localhost::9999?r=my_room</span></pre><br />Now we can launch the two browsers. Next time we will look at how we actually verify that the call worked, and how we actually download all resources needed by the test in a maintainable and automated manner. Stay tuned!<br /><br /><hr /><sup>1</sup>The explicit ports are because the default ports collided on the bots we were running on, and the --skip_sdk_update_check was because the SDK stopped and asked us something if there was an update. <br /><br />]]></description>
				<content:encoded><![CDATA[<i>by Patrik Höglund </i><br /><br /><a href="http://www.webrtc.org/">WebRTC</a> enables real time peer-to-peer video and voice transfer in the browser, making it possible to build, among other things, a <a href="https://apprtc.appspot.com/">working video chat</a> with a <a href="https://github.com/GoogleChrome/webrtc/tree/master/samples/web/content/apprtc">small amount of Python and JavaScript</a>. As a web standard, it has several unusual properties which makes it hard to test. A regular web standard generally accepts HTML text and yields a bitmap as output (what you see in the browser). For WebRTC, we have real-time RTP media streams on one side being sent to another WebRTC-enabled endpoint. These RTP packets have been jumping across NAT, through firewalls and perhaps through TURN servers to deliver hopefully stutter-free and low latency media. <br /><br />WebRTC is probably the only web standard in which we need to test direct communication between Chrome and other browsers. Remember, WebRTC builds on peer-to-peer technology, which means we talk directly between browsers rather than through a server. Chrome, Firefox and Opera have announced support for WebRTC so far. To test interoperability, we set out to build an automated test to ensure that Chrome and Firefox can get a call up. This article describes how we implemented such a test and the tradeoffs we made along the way.<br /><br /><h3>Calling in WebRTC </h3>Setting up a WebRTC call requires passing  SDP blobs over a signaling connection. These blobs contain information on the capabilities of the endpoint, such as what media formats it supports and what preferences it has (for instance, perhaps the endpoint has VP8 decoding hardware, which means the endpoint will handle VP8 more efficiently than, say, H.264). By sending these blobs the endpoints can agree on what media format they will be sending between themselves and how to traverse the network between them. Once that is done, the browsers will talk directly to each other, and nothing gets sent over the signaling connection.<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-A6zQCufOABs/U_zvIGck2gI/AAAAAAAAAG0/FlqBUQ8h_XY/s1600/image00.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-A6zQCufOABs/U_zvIGck2gI/AAAAAAAAAG0/FlqBUQ8h_XY/s1600/image00.png" width="500" /></a></div><div style="text-align: center;"><i>Figure 1. Signaling and media connections.</i></div><br />How these blobs are sent is up to the application. Usually the browsers connect to some server which mediates the connection between the browsers, for instance by using a contact list or a room number. The <a href="https://apprtc.appspot.com/">AppRTC reference application</a> uses room numbers to pair up browsers and sends the SDP blobs from the browsers through the AppRTC server.<br /><br /><h3>Test Design</h3>Instead of designing a new signaling solution from scratch, we chose to use the AppRTC application we already had. This has the additional benefit of testing the AppRTC code, which we are also maintaining. We could also have used the small <a href="https://code.google.com/p/chromium/codesearch#chromium/src/third_party/libjingle/libjingle.gyp&amp;q=peerconnection_server&amp;sq=package:chromium&amp;type=cs&amp;l=289">peerconnection_server</a> binary and some JavaScript, which would give us additional flexibility in what to test. We chose to go with AppRTC since it effectively implements the signaling for us, leading to much less test code. <br /><br />We assumed we would be able to get hold of the latest nightly Firefox and be able to launch that with a given URL. For the Chrome side, we assumed we would be running in a browser test, i.e. on a complete Chrome with some test scaffolding around it. For the first sketch of the test, we imagined just connecting the browsers to the live <a href="http://apprtc.appspot.com/">apprtc.appspot.com</a> with some random room number. If the call got established, we would be able to look at the remote video feed on the Chrome side and verify that video was playing (for instance using the <a href="http://googlechrome.github.io/webrtc/samples/web/content/getusermedia-canvas">video+canvas grab trick</a>). Furthermore, we could verify that audio was playing, for instance by using <a href="http://googlechrome.github.io/webrtc/samples/web/content/getusermedia-volume">WebRTC getStats</a> to measure the audio track energy level. <br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-KLMJbuz7uGg/U_zvNllz-vI/AAAAAAAAAG8/JJK4j05TQOI/s1600/image01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-KLMJbuz7uGg/U_zvNllz-vI/AAAAAAAAAG8/JJK4j05TQOI/s1600/image01.png" width="500" /></a></div><div style="text-align: center;"><i>Figure 2. Basic test design.</i></div><br />However, since we like tests to be <a href="http://googletesting.blogspot.se/2012/10/hermetic-servers.html">hermetic</a>, this isn’t a good design. I can see several problems. For example, if the network between us and AppRTC is unreliable. Also, what if someone has occupied myroomid? If that were the case, the test would fail and we would be none the wiser. So to make this thing work, we would have to find some way to bring up the AppRTC instance on localhost to make our test hermetic.<br /><br /><h3>Bringing up AppRTC on localhost</h3>AppRTC is a <a href="https://developers.google.com/appengine/">Google App Engine application</a>. As this <a href="https://developers.google.com/appengine/docs/python/gettingstartedpython27/helloworld">hello world example</a> demonstrates, one can test applications locally with<br /><pre style="background: #f0f0f0; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;">google_appengine/dev_appserver.py apprtc_code/</pre><br />So why not just call this from our test? It turns out we need to solve some complicated problems first, like how to ensure the AppEngine SDK and the AppRTC code is actually available on the executing machine, but we’ll get to that later. Let’s assume for now that stuff is just available. We can now write the browser test code to launch the local instance:<br /><pre style="background: #f0f0f0; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;"><span style="color: #0433ff;">bool</span> LaunchApprtcInstanceOnLocalhost() <br />  <span style="color: #4f8f00;">// ... Figure out locations of SDK and apprtc code ...</span><br />  CommandLine command_line(CommandLine::NO_PROGRAM);<br />  EXPECT_TRUE(GetPythonCommand(&amp;command_line));<br /><br />  command_line.AppendArgPath(appengine_dev_appserver);<br />  command_line.AppendArgPath(apprtc_dir);<br />  command_line.AppendArg(<span style="color: #ff2600;">"--port=9999"</span>);<br />  command_line.AppendArg(<span style="color: #ff2600;">"--admin_port=9998"</span>);<br />  command_line.AppendArg(<span style="color: #ff2600;">"--skip_sdk_update_check"</span>);<br /><br />  VLOG(1) &lt;&lt; <span style="color: #ff2600;">"Running "</span> &lt;&lt; command_line.GetCommandLineString();<br />  <span style="color: #0433ff;">return</span> base::LaunchProcess(command_line, base::LaunchOptions(),<br />                             &amp;dev_appserver_);<br />}<br /></pre><br />That’s pretty straightforward <a href="http://googletesting.blogspot.com/2014/08/chrome-firefox-webrtc-interop-test-pt-1.html#foot1"><sup>[1]</sup></a>.<br /><br /><h3>Figuring out Whether the Local Server is Up&nbsp;</h3>Then we ran into a very typical test problem. So we have the code to get the server up, and launching the two browsers to connect to <span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>http://localhost:9999?r=some_room</b></span> is easy. But how do we know when to connect? When I first ran the test, it would work sometimes and sometimes not depending on if the server had time to get up. <br /><br />It’s tempting in these situations to just add a sleep to give the server time to get up. Don’t do that. That will result in a test that is flaky and/or slow. In these situations we need to identify what we’re really waiting for. We could probably monitor the stdout of the <b><span style="color: #38761d; font-family: Courier New, Courier, monospace;">dev_appserver.py</span></b> and look for some message that says “Server is up!” or equivalent. However, we’re really waiting for the server to be able to serve web pages, and since we have two browsers that are really good at connecting to servers, why not use them? Consider this code.<br /><pre style="background: #f0f0f0; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;"><span style="color: #0433ff;">bool</span> LocalApprtcInstanceIsUp() {<br />  <span style="color: #4f8f00;">// Load the admin page and see if we manage to load it right.</span><br />  ui_test_utils::NavigateToURL(browser(), GURL(<span style="color: #ff2600;">"localhost:9998"</span>));<br />  content::WebContents* tab_contents =<br />      browser()-&gt;tab_strip_model()-&gt;GetActiveWebContents();<br />  std::<span style="color: #0433ff;">string</span> javascript =<br />      <span style="color: #ff2600;">"window.domAutomationController.send(document.title)"</span>;<br />  std::<span style="color: #0433ff;">string</span> result;<br />  <span style="color: #0433ff;">if</span> (!content::ExecuteScriptAndExtractString(tab_contents, <br />                                              javascript,<br />                                              &amp;result))<br />    <span style="color: #0433ff;">return</span> <span style="color: #0433ff;">false</span>;<br /><br />  <span style="color: #0433ff;">return</span> result == kTitlePageOfAppEngineAdminPage;<br />}<br /></pre><br />Here we ask Chrome to load the AppEngine admin page for the local server (we set the admin port to <span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>9998</b></span> earlier, remember?) and ask it what its title is. If that title is “Instances”, the admin page has been displayed, and the server must be up. If the server isn’t up, Chrome will fail to load the page and the title will be something like “<span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>localhost:9999</b></span> is not available”. <br /><br />Then, we can just do this from the test:<br /><pre style="background: #f0f0f0; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;"><span style="color: #0433ff;">while</span> (!LocalApprtcInstanceIsUp())<br />  VLOG(1) &lt;&lt; <span style="color: #ff2600;">"Waiting for AppRTC to come up..."</span>;<br /></pre><br />If the server never comes up, for whatever reason, the test will just time out in that loop. If it comes up we can safely proceed with the rest of test.<br /><br /><h3>Launching the Browsers&nbsp;</h3>A browser window launches itself as a part of every Chromium browser test. It’s also easy for the test to control the command line switches the browser will run under. <br /><br />We have less control over the Firefox browser since it is the “foreign” browser in this test, but we can still pass command-line options to it when we invoke the Firefox process. To make this easier, Mozilla provides a Python library called mozrunner. Using that we can set up a <a href="http://chromegw/viewvc/chrome/trunk/deps/third_party/webrtc/webrtc.DEPS/run_firefox_webrtc.py?revision=240895&amp;view=markup">launcher python script</a> we can invoke from the test:<br /><pre style="background: #f0f0f0; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;"><span style="color: #0433ff;">from</span> mozprofile <span style="color: #0433ff;">import</span> profile<br /><span style="color: #0433ff;">from</span> mozrunner <span style="color: #0433ff;">import</span> runner<br /><br />WEBRTC_PREFERENCES = {<br />    <span style="color: #ff2600;">'media.navigator.permission.disabled'</span>: True,<br />}<br /><br /><span style="color: #0433ff;">def</span> main():<br />  <span style="color: #4f8f00;"># Set up flags, handle SIGTERM, etc</span><br />  <span style="color: #4f8f00;"># ...</span><br />  firefox_profile = <br />      profile.FirefoxProfile(preferences=WEBRTC_PREFERENCES)<br />  firefox_runner = runner.FirefoxRunner(<br />      profile=firefox_profile, binary=options.binary, <br />      cmdargs=[options.webpage])<br /><br />  firefox_runner.start()</pre><br />Notice that we need to pass special preferences to make Firefox accept the getUserMedia prompt. Otherwise, the test would get stuck on the prompt and we would be unable to set up a call. Alternatively, we could employ some kind of clickbot to click “Allow” on the prompt when it pops up, but that is way harder to set up. <br /><br />Without going into too much detail, the code for launching the browsers becomes<br /><pre style="background: #f0f0f0; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;">GURL room_url = <br />    GURL(base::StringPrintf(<span style="color: #ff2600;">"http://localhost:9999?r=room_%d"</span>,<br />                            base::RandInt(0, 65536)));<br />content::WebContents* chrome_tab = <br />    OpenPageAndAcceptUserMedia(room_url);<br />ASSERT_TRUE(LaunchFirefoxWithUrl(room_url));</pre><br />Where LaunchFirefoxWithUrl essentially runs this:<br /><pre style="background: #f0f0f0; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;">run_firefox_webrtc.py --binary /path/to/firefox --webpage http:<span style="color: #4f8f00;">//localhost::9999?r=my_room</span></pre><br />Now we can launch the two browsers. Next time we will look at how we actually verify that the call worked, and how we actually download all resources needed by the test in a maintainable and automated manner. Stay tuned!<br /><br /><hr /><sup id="foot1">1</sup>The explicit ports are because the default ports collided on the bots we were running on, and the --skip_sdk_update_check was because the SDK stopped and asked us something if there was an update. <br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/chrome-firefox-webrtc-interop-test-pt-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Testing on the Toilet: Web Testing Made Easier: Debug IDs</title>
		<link>https://googledata.org/google-testing/testing-on-the-toilet-web-testing-made-easier-debug-ids/</link>
		<comments>https://googledata.org/google-testing/testing-on-the-toilet-web-testing-made-easier-debug-ids/#comments</comments>
		<pubDate>Tue, 12 Aug 2014 18:53:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=ae4fdc72c921e8e6aef981115504969a</guid>
		<description><![CDATA[<i>by Ruslan Khamitov&#160;</i><br /><i><br /></i><i>This article was adapted from a <a href="http://googletesting.blogspot.com/2007/01/introducing-testing-on-toilet.html">Google Testing on the Toilet (TotT) episode</a>. You can download a <a href="https://docs.google.com/document/d/1zHky363AF_eNVGOgnpD-7ouhjTG7QbYmCmGwbeFKruE/edit?usp=sharing">printer-friendly version</a> of this TotT episode and post it in your office.</i><br /><br /><b><span>Adding ID attributes to elements can make it much easier to write tests that interact with the DOM</span></b> (e.g., WebDriver tests). Consider the following DOM with two buttons that differ only by inner text:<br /><table><tbody><tr><td>Save button</td><td>Edit button</td></tr><tr><td><pre>&#60;div class="button"&#62;Save&#60;/div&#62;</pre></td><td><pre>&#60;div class="button"&#62;Edit&#60;/div&#62;</pre></td></tr></tbody></table><br />How would you tell WebDriver to interact with the &#8220;Save&#8221; button in this case?  You have several options.  <b><span>One option is to interact with the button using a CSS selector:</span></b><br /><pre>div.button</pre><br />However, this approach is not sufficient to identify a particular button, and there is no mechanism to filter by text in CSS. <b><span>Another option would be to write an XPath, which is generally fragile and discouraged:</span></b><br /><pre>//div[@class='button' and text()='Save']</pre><br /><b><span>Your best option is to add unique hierarchical IDs</span></b> where each widget is passed a base ID that it prepends to the ID of each of its children. The IDs for each button will be:<br /><pre><b><i>contact-form</i>.save-button<br /><i>contact-form</i>.edit-button</b></pre><br /><b><span>In GWT you can accomplish this by overriding onEnsureDebugId()on your widgets</span></b>. Doing so allows you to create custom logic for applying debug IDs to the sub-elements that make up a custom widget:<br /><pre>@Override <span>protected</span> <span>void</span> <b>onEnsureDebugId</b>(String baseId) {<br /><span>super</span>.<b>onEnsureDebugId</b>(baseId);<br />  saveButton.<b>ensureDebugId</b>(baseId + <span>".save-button"</span>);<br />  editButton.<b>ensureDebugId</b>(baseId + <span>".edit-button"</span>);<br />}</pre><br />Consider another example. <b><span>Let&#8217;s set IDs for repeated UI elements in Angular</span></b> using ng-repeat.  Setting an index can help differentiate between repeated instances of each element:<br /><pre>&#60;tr <b>id="feedback-{{$index}}</b>" class="feedback" ng-repeat="feedback in ctrl.feedbacks" &#62;</pre><br /><b><span>In GWT you can do this with ensureDebugId()</span></b>. Let&#8217;s set an ID for each of the table cells:<br /><pre>@UiField FlexTable table;<br />UIObject.ensureDebugId(table.getCellFormatter().getElement(rowIndex, columnIndex),<br /><b>baseID</b> + <b>colIndex</b> + <span>"-"</span> + <b>rowIndex</b>);</pre><br /><span><b>Take-away: Debug IDs are easy to set and make a huge difference for testing</b></span>. Please add them early.<br /><br />]]></description>
				<content:encoded><![CDATA[<i>by Ruslan Khamitov&nbsp;</i><br /><i><br /></i><i>This article was adapted from a <a href="http://googletesting.blogspot.com/2007/01/introducing-testing-on-toilet.html">Google Testing on the Toilet (TotT) episode</a>. You can download a <a href="https://docs.google.com/document/d/1zHky363AF_eNVGOgnpD-7ouhjTG7QbYmCmGwbeFKruE/edit?usp=sharing">printer-friendly version</a> of this TotT episode and post it in your office.</i><br /><br /><b><span style="color: #990000;">Adding ID attributes to elements can make it much easier to write tests that interact with the DOM</span></b> (e.g., WebDriver tests). Consider the following DOM with two buttons that differ only by inner text:<br /><table style="border-collapse: collapse; border: 1px solid black; width: 100%;"><tbody><tr><td style="border: 1px solid black; text-align: center;">Save button</td><td style="border: 1px solid black; text-align: center;">Edit button</td></tr><tr><td style="background: #cfe2f3; border: 1px solid black;"><pre style="background: #cfe2f3; border-color: #7b7b7b; border-style: solid; border-width: 0px; color: black; overflow: auto; padding: 0px 5px;">&lt;div class="button"&gt;Save&lt;/div&gt;</pre></td><td style="background: #cfe2f3; border: 1px solid black;"><pre style="background: #cfe2f3; border-color: #7b7b7b; border-style: solid; border-width: 0px; color: black; overflow: auto; padding: 0px 5px;">&lt;div class="button"&gt;Edit&lt;/div&gt;</pre></td></tr></tbody></table><br />How would you tell WebDriver to interact with the “Save” button in this case?  You have several options.  <b><span style="color: #990000;">One option is to interact with the button using a CSS selector:</span></b><br /><pre style="background: #cfe2f3; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;">div.button</pre><br />However, this approach is not sufficient to identify a particular button, and there is no mechanism to filter by text in CSS. <b><span style="color: #990000;">Another option would be to write an XPath, which is generally fragile and discouraged:</span></b><br /><pre style="background: #cfe2f3; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;">//div[@class='button' and text()='Save']</pre><br /><b><span style="color: #990000;">Your best option is to add unique hierarchical IDs</span></b> where each widget is passed a base ID that it prepends to the ID of each of its children. The IDs for each button will be:<br /><pre style="background: #d9ead3; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;"><b><i>contact-form</i>.save-button<br /><i>contact-form</i>.edit-button</b></pre><br /><b><span style="color: #990000;">In GWT you can accomplish this by overriding onEnsureDebugId()on your widgets</span></b>. Doing so allows you to create custom logic for applying debug IDs to the sub-elements that make up a custom widget:<br /><pre style="background: #d9ead3; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;">@Override <span style="color: #0433ff;">protected</span> <span style="color: #0433ff;">void</span> <b>onEnsureDebugId</b>(String baseId) {<br />  <span style="color: #0433ff;">super</span>.<b>onEnsureDebugId</b>(baseId);<br />  saveButton.<b>ensureDebugId</b>(baseId + <span style="color: #ff2600;">".save-button"</span>);<br />  editButton.<b>ensureDebugId</b>(baseId + <span style="color: #ff2600;">".edit-button"</span>);<br />}</pre><br />Consider another example. <b><span style="color: #990000;">Let’s set IDs for repeated UI elements in Angular</span></b> using ng-repeat.  Setting an index can help differentiate between repeated instances of each element:<br /><pre style="background: #d9ead3; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;">&lt;tr <b>id="feedback-{{$index}}</b>" class="feedback" ng-repeat="feedback in ctrl.feedbacks" &gt;</pre><br /><b><span style="color: #990000;">In GWT you can do this with ensureDebugId()</span></b>. Let’s set an ID for each of the table cells:<br /><pre style="background: #d9ead3; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;">@UiField FlexTable table;<br />UIObject.ensureDebugId(table.getCellFormatter().getElement(rowIndex, columnIndex),<br />    <b>baseID</b> + <b>colIndex</b> + <span style="color: #ff2600;">"-"</span> + <b>rowIndex</b>);</pre><br /><span style="color: #990000;"><b>Take-away: Debug IDs are easy to set and make a huge difference for testing</b></span>. Please add them early.<br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/testing-on-the-toilet-web-testing-made-easier-debug-ids/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Testing on the Toilet: Don&#8217;t Put Logic in Tests</title>
		<link>https://googledata.org/google-testing/testing-on-the-toilet-dont-put-logic-in-tests/</link>
		<comments>https://googledata.org/google-testing/testing-on-the-toilet-dont-put-logic-in-tests/#comments</comments>
		<pubDate>Thu, 31 Jul 2014 16:59:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=9eeb5e6826db4d7b82d9a2526e1eb76f</guid>
		<description><![CDATA[<i>by Erik Kuefler </i><br /><i><br /></i><i>This article was adapted from a <a href="http://googletesting.blogspot.com/2007/01/introducing-testing-on-toilet.html">Google Testing on the Toilet</a> (TotT) episode. You can download a <a href="https://docs.google.com/document/d/1f-ISrr6ItyDCJCMaFXOyQBZmekBZwxQ0tZeksoWUZAo/edit?usp=sharing">printer-friendly version</a> of this TotT episode and post it in your office.  </i><br /><br /><b><span>Programming languages give us a lot of expressive power.</span></b> Concepts like operators and conditionals are important tools that allow us to write programs that handle a wide range of inputs. But <b><span>this flexibility comes at the cost of increased complexity</span></b>, which makes our programs harder to understand. <br /><br />Unlike production code, <b><span>simplicity is more important than flexibility in tests</span></b>. Most unit tests verify that a single, known input produces a single, known output. <b><span>Tests can avoid complexity by stating their inputs and outputs directly rather than computing them</span></b>. Otherwise it's easy for tests to develop their own bugs.<br /><br />Let's take a look at a simple example. <b><span>Does this test look correct to you? </span></b><br /><br /><pre>@Test <span>public</span> <span>void</span> shouldNavigateToPhotosPage() {<br />  String <b>baseUrl</b> = <span>"http://plus.google.com/"</span>;<br />  Navigator nav = <span>new</span> Navigator(<b>baseUrl</b>);<br />  nav.goToPhotosPage();<br />  assertEquals(<b>baseUrl</b> + <span><b>"/u/0/photos"</b></span>, nav.getCurrentUrl());<br />}</pre><br />The author is trying to avoid duplication by storing a shared prefix in a variable. Performing a single string concatenation doesn't seem too bad, but <b><span>what happens if we simplify the test by inlining the variable? </span></b><br /><br /><pre>@Test <span>public</span> <span>void</span> shouldNavigateToPhotosPage() {<br />  Navigator nav = <span>new</span> Navigator(<span>"http://plus.google.com/"</span>);<br />  nav.goToPhotosPage();<br />  assertEquals(<span>"<b>http://plus.google.com//u/0/photos</b>"</span>, nav.getCurrentUrl()); <span>// <b>Oops!</b></span><br />}</pre><br /><b><span>After eliminating the unnecessary computation from the test, the bug is obvious</span></b>&#8212;we're expecting two slashes in the URL! This test will either fail or (even worse) incorrectly pass if the production code has the same bug. We never would have written this if we stated our inputs and outputs directly instead of trying to compute them. And this is a very simple example&#8212;<span><b>when a test adds more operators or includes loops and conditionals, it becomes increasingly difficult to be confident that it is correct. </b></span><br /><br />Another way of saying this is that, <b><span>whereas production code describes a general strategy for computing outputs given inputs, tests are concrete examples of input/output pairs</span></b> (where output might include side effects like verifying interactions with other classes). It's usually easy to tell whether an input/output pair is correct or not, even if the logic required to compute it is very complex. For instance, it's hard to picture the exact DOM that would be created by a Javascript function for a given server response. So the ideal test for such a function would just compare against a string containing the expected output HTML. <br /><br /><b><span>When tests do need their own logic, such logic should often be moved out of the test bodies and into utilities and helper functions</span></b>. Since such helpers can get quite complex, it's usually a good idea for any nontrivial test utility to have its own tests.<br /><br />]]></description>
				<content:encoded><![CDATA[<i>by Erik Kuefler </i><br /><i><br /></i><i>This article was adapted from a <a href="http://googletesting.blogspot.com/2007/01/introducing-testing-on-toilet.html">Google Testing on the Toilet</a> (TotT) episode. You can download a <a href="https://docs.google.com/document/d/1f-ISrr6ItyDCJCMaFXOyQBZmekBZwxQ0tZeksoWUZAo/edit?usp=sharing">printer-friendly version</a> of this TotT episode and post it in your office.  </i><br /><br /><b><span style="color: #990000;">Programming languages give us a lot of expressive power.</span></b> Concepts like operators and conditionals are important tools that allow us to write programs that handle a wide range of inputs. But <b><span style="color: #990000;">this flexibility comes at the cost of increased complexity</span></b>, which makes our programs harder to understand. <br /><br />Unlike production code, <b><span style="color: #990000;">simplicity is more important than flexibility in tests</span></b>. Most unit tests verify that a single, known input produces a single, known output. <b><span style="color: #990000;">Tests can avoid complexity by stating their inputs and outputs directly rather than computing them</span></b>. Otherwise it's easy for tests to develop their own bugs.<br /><br />Let's take a look at a simple example. <b><span style="color: #990000;">Does this test look correct to you? </span></b><br /><br /><pre style="background: #f0f0f0; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;">@Test <span style="color: #0433ff;">public</span> <span style="color: #0433ff;">void</span> shouldNavigateToPhotosPage() {<br />  String <b>baseUrl</b> = <span style="color: #ff2600;">"http://plus.google.com/"</span>;<br />  Navigator nav = <span style="color: #0433ff;">new</span> Navigator(<b>baseUrl</b>);<br />  nav.goToPhotosPage();<br />  assertEquals(<b>baseUrl</b> + <span style="color: #ff2600;"><b>"/u/0/photos"</b></span>, nav.getCurrentUrl());<br />}</pre><br />The author is trying to avoid duplication by storing a shared prefix in a variable. Performing a single string concatenation doesn't seem too bad, but <b><span style="color: #990000;">what happens if we simplify the test by inlining the variable? </span></b><br /><br /><pre style="background: #f0f0f0; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;">@Test <span style="color: #0433ff;">public</span> <span style="color: #0433ff;">void</span> shouldNavigateToPhotosPage() {<br />  Navigator nav = <span style="color: #0433ff;">new</span> Navigator(<span style="color: #ff2600;">"http://plus.google.com/"</span>);<br />  nav.goToPhotosPage();<br />  assertEquals(<span style="color: #ff2600;">"<b>http://plus.google.com//u/0/photos</b>"</span>, nav.getCurrentUrl()); <span style="color: #4f8f00;">// <b>Oops!</b></span><br />}</pre><br /><b><span style="color: #990000;">After eliminating the unnecessary computation from the test, the bug is obvious</span></b>—we're expecting two slashes in the URL! This test will either fail or (even worse) incorrectly pass if the production code has the same bug. We never would have written this if we stated our inputs and outputs directly instead of trying to compute them. And this is a very simple example—<span style="color: #990000;"><b>when a test adds more operators or includes loops and conditionals, it becomes increasingly difficult to be confident that it is correct. </b></span><br /><br />Another way of saying this is that, <b><span style="color: #990000;">whereas production code describes a general strategy for computing outputs given inputs, tests are concrete examples of input/output pairs</span></b> (where output might include side effects like verifying interactions with other classes). It's usually easy to tell whether an input/output pair is correct or not, even if the logic required to compute it is very complex. For instance, it's hard to picture the exact DOM that would be created by a Javascript function for a given server response. So the ideal test for such a function would just compare against a string containing the expected output HTML. <br /><br /><b><span style="color: #990000;">When tests do need their own logic, such logic should often be moved out of the test bodies and into utilities and helper functions</span></b>. Since such helpers can get quite complex, it's usually a good idea for any nontrivial test utility to have its own tests.<br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/testing-on-the-toilet-dont-put-logic-in-tests/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>The Deadline to Sign up for GTAC 2014 is Jul 28</title>
		<link>https://googledata.org/google-testing/the-deadline-to-sign-up-for-gtac-2014-is-jul-28/</link>
		<comments>https://googledata.org/google-testing/the-deadline-to-sign-up-for-gtac-2014-is-jul-28/#comments</comments>
		<pubDate>Wed, 23 Jul 2014 00:53:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=54605ca45a93ef96fb4fe92e634cc9be</guid>
		<description><![CDATA[<i>Posted by Anthony Vallone on behalf of the GTAC Committee </i><br /><br />The deadline to sign up for GTAC 2014 is next Monday, July 28th, 2014. There is a great deal of interest to both attend and speak, and we&#8217;ve received many outstanding proposals. However, it&#8217;s not too late to add yours for consideration. If you would like to speak or attend, be sure to <a href="https://docs.google.com/a/google.com/forms/d/1HVm6KcFBdQAbhX_uh6LEjVYI1ZCCr-L9t7ocbtvLIMU/viewform">complete the form</a> by Monday.  <br /><br />We will be making regular updates to our site over the next several weeks, and you can find conference details there:<br />&#160; <a href="http://developers.google.com/gtac">developers.google.com/gtac</a><br /><br />For those that have already signed up to attend or speak, we will contact you directly in mid August. <br /><br />]]></description>
				<content:encoded><![CDATA[<i>Posted by Anthony Vallone on behalf of the GTAC Committee </i><br /><br />The deadline to sign up for GTAC 2014 is next Monday, July 28th, 2014. There is a great deal of interest to both attend and speak, and we’ve received many outstanding proposals. However, it’s not too late to add yours for consideration. If you would like to speak or attend, be sure to <a href="https://docs.google.com/a/google.com/forms/d/1HVm6KcFBdQAbhX_uh6LEjVYI1ZCCr-L9t7ocbtvLIMU/viewform">complete the form</a> by Monday.  <br /><br />We will be making regular updates to our site over the next several weeks, and you can find conference details there:<br />&nbsp; <a href="http://developers.google.com/gtac">developers.google.com/gtac</a><br /><br />For those that have already signed up to attend or speak, we will contact you directly in mid August. <br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/the-deadline-to-sign-up-for-gtac-2014-is-jul-28/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Measuring Coverage at Google</title>
		<link>https://googledata.org/google-testing/measuring-coverage-at-google/</link>
		<comments>https://googledata.org/google-testing/measuring-coverage-at-google/#comments</comments>
		<pubDate>Mon, 14 Jul 2014 19:42:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=41e09e054a805e409acdc753a8dafe10</guid>
		<description><![CDATA[<i>By Marko Ivankovi&#263;, Google Z&#252;rich</i><br /><br /><h3>Introduction</h3><br /><a href="http://en.wikipedia.org/wiki/Code_coverage">Code coverage</a> is a very interesting metric, covered by a <a href="http://scholar.google.com/scholar?q=%22code+coverage%22">large body of research</a> that reaches somewhat contradictory results. Some people think it is an extremely useful metric and that a certain percentage of coverage should be enforced on all code. Some think it is a useful tool to identify areas that need more testing but don&#8217;t necessarily trust that covered code is truly well tested. Others yet think that measuring coverage is actively harmful because it provides a false sense of security. <br /><br />Our team&#8217;s mission was to collect coverage related data then develop and champion code coverage practices across Google. We designed an opt-in system where engineers could enable two different types of coverage measurements for their projects: daily and per-commit. With daily coverage, we run all tests for their project, where as with per-commit coverage we run only the tests affected by the commit. The two measurements are independent and many projects opted into both. <br /><br />While we did experiment with branch, function and statement coverage, we ended up focusing mostly on statement coverage because of its relative simplicity and ease of visualization.<br /><br /><h3>How we measured </h3><br />Our job was made significantly easier by the wonderful <a href="http://google-engtools.blogspot.ch/2011/08/build-in-cloud-how-build-system-works.html">Google build system</a> whose parallelism and flexibility allowed us to simply scale our measurements to Google scale. The build system had integrated various language-specific open source coverage measurement tools like <a href="https://gcc.gnu.org/onlinedocs/gcc/Gcov.html">Gcov</a> (C++), <a href="http://emma.sourceforge.net/">Emma</a> / <a href="http://www.eclemma.org/jacoco/">JaCoCo</a> (Java) and <a href="https://pypi.python.org/pypi/coverage/3.7.1">Coverage.py</a> (Python), and we provided a central system where teams could sign up for coverage measurement.<br /><br />For daily whole project coverage measurements, each team was provided with a simple cronjob that would run all tests across the project&#8217;s codebase. The results of these runs were available to the teams in a centralized dashboard that displays charts showing coverage over time and allows daily / weekly / quarterly / yearly aggregations and per-language slicing. On this dashboard teams can also compare their project (or projects) with any other project, or Google as a whole. <br /><br />For per-commit measurement, we hook into the Google code review process (<a href="http://googletesting.blogspot.ch/2014/01/the-google-test-and-development_21.html">briefly explained in this article</a>) and display the data visually to both the commit author and the reviewers. We display the data on two levels: color coded lines right next to the color coded diff and a total aggregate number for the entire commit.  <br /><br /><div><a href="http://1.bp.blogspot.com/-cWVgcOaZRyA/U8QuI4RynII/AAAAAAAAAGc/nAbVkwYjTBg/s1600/image01.png"><img border="0" src="http://1.bp.blogspot.com/-cWVgcOaZRyA/U8QuI4RynII/AAAAAAAAAGc/nAbVkwYjTBg/s1600/image01.png" height="145" width="400"></a></div><br />Displayed above is a screenshot of the code review tool. The green line coloring is the standard diff coloring for added lines. The orange and lighter green coloring on the line <b>numbers</b> is the coverage information. We use light green for covered lines, orange for non-covered lines and white for non-instrumented lines. <br /><br />It&#8217;s important to note that we surface the coverage information <b>before</b> the commit is submitted to the codebase, because this is the time when engineers are most likely to be interested in improving it.<br /><br /><h3>Results</h3><br />One of the main benefits of working at Google is the scale at which we operate. We have been running the coverage measurement system for some time now and we have collected data for more than 650 different projects, spanning 100,000+ commits. We have a significant amount of data for C++, Java, Python, Go and JavaScript code. <br /><br />I am happy to say that we can share some preliminary results with you today: <br /><br /><div><a href="http://4.bp.blogspot.com/-FBwOXyefWMw/U8QuPBBZa2I/AAAAAAAAAGk/lvzZNmyB_bI/s1600/image00.png"><img border="0" src="http://4.bp.blogspot.com/-FBwOXyefWMw/U8QuPBBZa2I/AAAAAAAAAGk/lvzZNmyB_bI/s1600/image00.png" height="262" width="640"></a></div><br />The chart above is the histogram of average values of measured absolute coverage across Google. The median (50th percentile) code coverage is 78%, the 75th percentile 85% and 90th percentile 90%. We believe that these numbers represent a very healthy codebase. <br /><br />We have also found it very interesting that there are significant differences between languages:  <br /><br /><table><tbody><tr><td>C++</td><td>Java</td><td>Go</td><td>JavaScript</td><td>Python</td></tr><tr><td>56.6%</td><td>61.2%</td><td>63.0%</td><td>76.9%</td><td>84.2%</td></tr></tbody></table><br /><br />The table above shows the total coverage of all analyzed code for each language, averaged over the past quarter. We believe that the large difference is due to structural, paradigm and best practice differences between languages and the more precise ability to measure coverage in certain languages. <br /><br />Note that these numbers should not be interpreted as guidelines for a particular language, the aggregation method used is too simple for that. Instead this finding is simply a data point for any future research that analyzes samples from a single programming language. <br /><br />The feedback from our fellow engineers was overwhelmingly positive. The most loved feature was surfacing the coverage information during code review time. This early surfacing of coverage had a statistically significant impact: our initial analysis suggests that it increased coverage by 10% (averaged across all commits).<br /><br /><h3>Future work</h3><br />We are aware that there are a few problems with the dataset we collected. In particular, the individual tools we use to measure coverage are not perfect. Large integration tests, end to end tests and UI tests are difficult to instrument, so large parts of code exercised by such tests can be misreported as non-covered. <br /><br />We are working on improving the tools, but also analyzing the impact of unit tests, integration tests and other types of tests individually.  <br /><br />In addition to languages, we will also investigate other factors that might influence coverage, such as platforms and frameworks, to allow all future research to account for their effect. <br /><br />We will be publishing more of our findings in the future, so stay tuned. <br /><br />And if this sounds like something you would like to work on, why not apply on our <a href="http://goo.gl/tFRejX">job site</a>? <br /><br />]]></description>
				<content:encoded><![CDATA[<i>By Marko Ivanković, Google Zürich</i><br /><br><h3>Introduction</h3><br><a href="http://en.wikipedia.org/wiki/Code_coverage">Code coverage</a> is a very interesting metric, covered by a <a href="http://scholar.google.com/scholar?q=%22code+coverage%22">large body of research</a> that reaches somewhat contradictory results. Some people think it is an extremely useful metric and that a certain percentage of coverage should be enforced on all code. Some think it is a useful tool to identify areas that need more testing but don’t necessarily trust that covered code is truly well tested. Others yet think that measuring coverage is actively harmful because it provides a false sense of security. <br /><br />Our team’s mission was to collect coverage related data then develop and champion code coverage practices across Google. We designed an opt-in system where engineers could enable two different types of coverage measurements for their projects: daily and per-commit. With daily coverage, we run all tests for their project, where as with per-commit coverage we run only the tests affected by the commit. The two measurements are independent and many projects opted into both. <br /><br />While we did experiment with branch, function and statement coverage, we ended up focusing mostly on statement coverage because of its relative simplicity and ease of visualization.<br /><br><h3>How we measured </h3><br />Our job was made significantly easier by the wonderful <a href="http://google-engtools.blogspot.ch/2011/08/build-in-cloud-how-build-system-works.html">Google build system</a> whose parallelism and flexibility allowed us to simply scale our measurements to Google scale. The build system had integrated various language-specific open source coverage measurement tools like <a href="https://gcc.gnu.org/onlinedocs/gcc/Gcov.html">Gcov</a> (C++), <a href="http://emma.sourceforge.net/">Emma</a> / <a href="http://www.eclemma.org/jacoco/">JaCoCo</a> (Java) and <a href="https://pypi.python.org/pypi/coverage/3.7.1">Coverage.py</a> (Python), and we provided a central system where teams could sign up for coverage measurement.<br /><br />For daily whole project coverage measurements, each team was provided with a simple cronjob that would run all tests across the project’s codebase. The results of these runs were available to the teams in a centralized dashboard that displays charts showing coverage over time and allows daily / weekly / quarterly / yearly aggregations and per-language slicing. On this dashboard teams can also compare their project (or projects) with any other project, or Google as a whole. <br /><br />For per-commit measurement, we hook into the Google code review process (<a href="http://googletesting.blogspot.ch/2014/01/the-google-test-and-development_21.html">briefly explained in this article</a>) and display the data visually to both the commit author and the reviewers. We display the data on two levels: color coded lines right next to the color coded diff and a total aggregate number for the entire commit.  <br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-cWVgcOaZRyA/U8QuI4RynII/AAAAAAAAAGc/nAbVkwYjTBg/s1600/image01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-cWVgcOaZRyA/U8QuI4RynII/AAAAAAAAAGc/nAbVkwYjTBg/s1600/image01.png" height="145" width="400" /></a></div><br />Displayed above is a screenshot of the code review tool. The green line coloring is the standard diff coloring for added lines. The orange and lighter green coloring on the line <b>numbers</b> is the coverage information. We use light green for covered lines, orange for non-covered lines and white for non-instrumented lines. <br /><br />It’s important to note that we surface the coverage information <b>before</b> the commit is submitted to the codebase, because this is the time when engineers are most likely to be interested in improving it.<br /><br><h3>Results</h3><br />One of the main benefits of working at Google is the scale at which we operate. We have been running the coverage measurement system for some time now and we have collected data for more than 650 different projects, spanning 100,000+ commits. We have a significant amount of data for C++, Java, Python, Go and JavaScript code. <br /><br />I am happy to say that we can share some preliminary results with you today: <br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-FBwOXyefWMw/U8QuPBBZa2I/AAAAAAAAAGk/lvzZNmyB_bI/s1600/image00.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-FBwOXyefWMw/U8QuPBBZa2I/AAAAAAAAAGk/lvzZNmyB_bI/s1600/image00.png" height="262" width="640" /></a></div><br />The chart above is the histogram of average values of measured absolute coverage across Google. The median (50th percentile) code coverage is 78%, the 75th percentile 85% and 90th percentile 90%. We believe that these numbers represent a very healthy codebase. <br /><br />We have also found it very interesting that there are significant differences between languages:  <br /><br /><table style="border-collapse: collapse; border: 1px solid black; width: 100%;"><tbody><tr><td style="border: 1px solid black; padding: 5px;">C++</td><td style="border: 1px solid black; padding: 5px;">Java</td><td style="border: 1px solid black; padding: 5px;">Go</td><td style="border: 1px solid black; padding: 5px;">JavaScript</td><td style="border: 1px solid black; padding: 5px;">Python</td></tr><tr><td style="border: 1px solid black; padding: 5px;">56.6%</td><td style="border: 1px solid black; padding: 5px;">61.2%</td><td style="border: 1px solid black; padding: 5px;">63.0%</td><td style="border: 1px solid black; padding: 5px;">76.9%</td><td style="border: 1px solid black; padding: 5px;">84.2%</td></tr></tbody></table><br /><br />The table above shows the total coverage of all analyzed code for each language, averaged over the past quarter. We believe that the large difference is due to structural, paradigm and best practice differences between languages and the more precise ability to measure coverage in certain languages. <br /><br />Note that these numbers should not be interpreted as guidelines for a particular language, the aggregation method used is too simple for that. Instead this finding is simply a data point for any future research that analyzes samples from a single programming language. <br /><br />The feedback from our fellow engineers was overwhelmingly positive. The most loved feature was surfacing the coverage information during code review time. This early surfacing of coverage had a statistically significant impact: our initial analysis suggests that it increased coverage by 10% (averaged across all commits).<br /><br><h3>Future work</h3><br />We are aware that there are a few problems with the dataset we collected. In particular, the individual tools we use to measure coverage are not perfect. Large integration tests, end to end tests and UI tests are difficult to instrument, so large parts of code exercised by such tests can be misreported as non-covered. <br /><br />We are working on improving the tools, but also analyzing the impact of unit tests, integration tests and other types of tests individually.  <br /><br />In addition to languages, we will also investigate other factors that might influence coverage, such as platforms and frameworks, to allow all future research to account for their effect. <br /><br />We will be publishing more of our findings in the future, so stay tuned. <br /><br />And if this sounds like something you would like to work on, why not apply on our <a href="http://goo.gl/tFRejX">job site</a>? <br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/measuring-coverage-at-google/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>ThreadSanitizer: Slaughtering Data Races</title>
		<link>https://googledata.org/google-testing/threadsanitizer-slaughtering-data-races/</link>
		<comments>https://googledata.org/google-testing/threadsanitizer-slaughtering-data-races/#comments</comments>
		<pubDate>Mon, 30 Jun 2014 21:30:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=dff169cd4b36bc049672bd674b44b0e0</guid>
		<description><![CDATA[by Dmitry Vyukov, Synchronization Lookout, Google, MoscowHello, I work in the Dynamic Testing Tools team at Google. Our team develops tools like AddressSanitizer, MemorySanitizer and ThreadSanitizer which find various kinds of bugs. In this blog post I...]]></description>
				<content:encoded><![CDATA[<i>by Dmitry Vyukov, Synchronization Lookout, Google, Moscow</i><br /><br />Hello, <br /><br />I work in the Dynamic Testing Tools team at Google. Our team develops tools like <a href="http://address-sanitizer.googlecode.com/">AddressSanitizer</a>, <a href="http://memory-sanitizer.googlecode.com/">MemorySanitizer</a> and <a href="http://thread-sanitizer.googlecode.com/">ThreadSanitizer</a> which find various kinds of bugs. In this blog post I want to tell you about ThreadSanitizer, a fast data race detector for C++ and Go programs. <br /><br />First of all, what is a <a href="http://en.wikipedia.org/wiki/Race_condition">data race</a>? A data race occurs when two threads access the same variable concurrently, and at least one of the accesses attempts is a write. Most programming languages provide very weak guarantees, or no guarantees at all, for programs with data races. For example, in C++ absolutely any data race renders the behavior of the whole program as completely undefined (yes, it can suddenly format the hard drive). Data races are common in concurrent programs, and they are notoriously hard to debug and localize. A typical manifestation of a data race is when a program occasionally crashes with obscure symptoms, the symptoms are different each time and do not point to any particular place in the source code. Such bugs can take several months of debugging without particular success, since typical debugging techniques do not work. Fortunately, ThreadSanitizer can catch most data races in the blink of an eye. See Chromium <a href="https://code.google.com/p/chromium/issues/detail?id=15577">issue 15577</a> for an example of such a data race and <a href="https://code.google.com/p/chromium/issues/detail?id=18488">issue 18488</a> for the resolution. <br /><br />Due to the complex nature of bugs caught by ThreadSanitizer, we don't suggest waiting until product release validation to use the tool. For example, in Google, we've made our tools easily accessible to programmers during development, so that anyone can use the tool for testing if they suspect that new code might introduce a race. For both Chromium and Google internal server codebase, we run unit tests that use the tool continuously. This catches many regressions instantly. The Chromium project has recently started using ThreadSanitizer on <a href="http://blog.chromium.org/2012/04/fuzzing-for-security.html">ClusterFuzz</a>, a large scale fuzzing system. Finally, some teams also set up periodic end-to-end testing with ThreadSanitizer under a realistic workload, which proves to be extremely valuable. When races are found by the tool, our team has zero tolerance for races and does not consider any race to be benign, as even the most benign races can lead to <a href="https://software.intel.com/en-us/blogs/2013/01/06/benign-data-races-what-could-possibly-go-wrong">memory corruption</a>. <br /><br />Our tools are <a href="http://en.wikipedia.org/wiki/Dynamic_program_analysis">dynamic</a> (as opposed to <a href="http://en.wikipedia.org/wiki/Static_analysis_tool">static tools</a>). This means that they do not merely "look" at the code and try to surmise where bugs can be; instead they they <a href="http://en.wikipedia.org/wiki/Instrumentation_(computer_programming)">instrument</a> the binary at build time and then analyze dynamic behavior of the program to catch it red-handed. This approach has its pros and cons. On one hand, the tool does not have any false positives, thus it does not bother a developer with something that is not a bug. On the other hand, in order to catch a bug, the test must expose a bug -- the racing data access attempts must be executed in different threads. This requires writing good multi-threaded tests and makes end-to-end testing especially effective. <br /><br />As a bonus, ThreadSanitizer finds some other types of bugs: thread leaks, deadlocks, incorrect uses of mutexes, malloc calls in signal handlers, and <a href="https://code.google.com/p/thread-sanitizer/wiki/DetectableBugs">more</a>. It also natively understands atomic operations and thus can find bugs in <a href="http://en.wikipedia.org/wiki/Lock-free">lock-free</a> algorithms (see e.g. <a href="https://code.google.com/p/chromium/issues/detail?id=330528">this bug</a> in the V8 concurrent garbage collector). <br /><br />The tool is supported by both Clang and GCC compilers (only on Linux/Intel64). Using it is very simple: you just need to add a <b><span style="color: #38761d; font-family: Courier New, Courier, monospace;">-fsanitize=thread</span></b> flag during compilation and linking. For Go programs, you simply need to add a <b><span style="color: #38761d; font-family: Courier New, Courier, monospace;">-race flag</span></b> to the go tool (supported on Linux, Mac and Windows). <br /><br />Interestingly, after integrating the tool into compilers, we've found some bugs in the compilers themselves. For example, LLVM was <a href="http://llvm.org/bugs/show_bug.cgi?id=13691">illegally widening stores</a>, which can introduce very harmful data races into otherwise correct programs. And GCC was injecting <a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48076">unsafe code</a> for initialization of function static variables. Among our other trophies are more than <a href="https://code.google.com/p/thread-sanitizer/wiki/FoundBugs">a thousand bugs</a> in Chromium, Firefox, the Go standard library, WebRTC, OpenSSL, and of course in our internal projects. <br /><br />So what are you waiting for? You know what to do! ]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/threadsanitizer-slaughtering-data-races/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>GTAC 2014: Call for Proposals &amp; Attendance</title>
		<link>https://googledata.org/google-testing/gtac-2014-call-for-proposals-attendance/</link>
		<comments>https://googledata.org/google-testing/gtac-2014-call-for-proposals-attendance/#comments</comments>
		<pubDate>Mon, 16 Jun 2014 21:57:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=21adc4a3d5d1734d009da7814ceaa55c</guid>
		<description><![CDATA[<i>Posted by Anthony Vallone on behalf of the GTAC Committee</i><br /><br />The application process is now open for presentation proposals and attendance for GTAC (Google Test Automation Conference) (<a href="http://googletesting.blogspot.com/2014/06/gtac-2014-coming-to-seattlekirkland-in.html">see initial announcement</a>) to be held at the <a href="http://www.google.com/about/careers/locations/seattle-kirkland/">Google Kirkland office (near Seattle, WA)</a> on October 28 - 29th, 2014.<br /><br />GTAC will be streamed live on YouTube again this year, so even if you can&#8217;t attend, you&#8217;ll be able to watch the conference from your computer.<br /><br /><b>Speakers</b><br />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.<br /><br /><b>Application</b><br />For presentation proposals and/or attendance, <a href="https://docs.google.com/forms/d/1HVm6KcFBdQAbhX_uh6LEjVYI1ZCCr-L9t7ocbtvLIMU/viewform?usp=send_form">complete this form</a>. We will be selecting about 300 applicants for the event.<br /><br /><b>Deadline</b><br />The due date for both presentation and attendance applications is July 28, 2014.<br /><br /><b>Fees</b><br />There are no registration fees, and we will send out detailed registration instructions to each invited applicant. Meals will be provided, but speakers and attendees must arrange and pay for their own travel and accommodations. <br /><br /><b><span>Update</span> : </b>Our <a href="https://developers.google.com/google-test-automation-conference/2014/contact">contact</a> email was bouncing - this is now fixed.<br /><br /><br /><div><a href="http://2.bp.blogspot.com/-ho3a6DukQw4/U59Eb4GsfdI/AAAAAAAAAGM/8jPcyc3_SHQ/s1600/GTAC+2014+logo.png"><img border="0" src="http://2.bp.blogspot.com/-ho3a6DukQw4/U59Eb4GsfdI/AAAAAAAAAGM/8jPcyc3_SHQ/s1600/GTAC+2014+logo.png" height="200" width="200"></a></div><br />]]></description>
				<content:encoded><![CDATA[<i>Posted by Anthony Vallone on behalf of the GTAC Committee</i><br /><br />The application process is now open for presentation proposals and attendance for GTAC (Google Test Automation Conference) (<a href="http://googletesting.blogspot.com/2014/06/gtac-2014-coming-to-seattlekirkland-in.html">see initial announcement</a>) to be held at the <a href="http://www.google.com/about/careers/locations/seattle-kirkland/">Google Kirkland office (near Seattle, WA)</a> on October 28 - 29th, 2014.<br /><br />GTAC will be streamed live on YouTube again this year, so even if you can’t attend, you’ll be able to watch the conference from your computer.<br /><br /><b>Speakers</b><br />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.<br /><br /><b>Application</b><br />For presentation proposals and/or attendance, <a href="https://docs.google.com/forms/d/1HVm6KcFBdQAbhX_uh6LEjVYI1ZCCr-L9t7ocbtvLIMU/viewform?usp=send_form">complete this form</a>. We will be selecting about 300 applicants for the event.<br /><br /><b>Deadline</b><br />The due date for both presentation and attendance applications is July 28, 2014.<br /><br /><b>Fees</b><br />There are no registration fees, and we will send out detailed registration instructions to each invited applicant. Meals will be provided, but speakers and attendees must arrange and pay for their own travel and accommodations. <br /><br /><b><span style="color: red;">Update</span> : </b>Our <a href="https://developers.google.com/google-test-automation-conference/2014/contact">contact</a> email was bouncing - this is now fixed.<br /><br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-ho3a6DukQw4/U59Eb4GsfdI/AAAAAAAAAGM/8jPcyc3_SHQ/s1600/GTAC+2014+logo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-ho3a6DukQw4/U59Eb4GsfdI/AAAAAAAAAGM/8jPcyc3_SHQ/s1600/GTAC+2014+logo.png" height="200" width="200" /></a></div><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/gtac-2014-call-for-proposals-attendance/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>GTAC 2014 Coming to Seattle/Kirkland in October</title>
		<link>https://googledata.org/google-testing/gtac-2014-coming-to-seattlekirkland-in-october/</link>
		<comments>https://googledata.org/google-testing/gtac-2014-coming-to-seattlekirkland-in-october/#comments</comments>
		<pubDate>Wed, 04 Jun 2014 19:21:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=41f5406d799a055857d2c076676ee25b</guid>
		<description><![CDATA[<i>Posted by Anthony Vallone on behalf of the GTAC Committee</i><br /><br />If you're looking for a place to discuss the latest innovations in test automation, then charge your tablets and pack your <a href="http://en.wikipedia.org/wiki/Wellington_boot">gumboots</a> - the  eighth <a href="https://developers.google.com/gtac/">GTAC</a> (Google Test Automation Conference) will be held on October 28-29, 2014 at Google Kirkland! The Kirkland office is part of the <a href="http://www.google.com/about/careers/locations/seattle-kirkland/">Seattle/Kirkland campus</a> in beautiful Washington state. This campus forms our third largest engineering office in the USA.<br /><br /><div><a href="http://3.bp.blogspot.com/-6pFux0LhOmA/U49xL6rnkrI/AAAAAAAAAF8/E8uecMVaSio/s1600/GTAC+2014+logo.png"><img border="0" src="http://3.bp.blogspot.com/-6pFux0LhOmA/U49xL6rnkrI/AAAAAAAAAF8/E8uecMVaSio/s1600/GTAC+2014+logo.png" height="200" width="200"></a></div><br /><br />GTAC is a periodic conference hosted by Google, bringing together engineers from industry and academia to discuss advances in test automation and the test engineering computer science field. It&#8217;s a great opportunity to present, learn, and challenge modern testing technologies and strategies.  <br /><br />You can browse the presentation abstracts, slides, and videos from last year on the <a href="https://developers.google.com/google-test-automation-conference/2013/">GTAC 2013 page</a>. <br /><br />Stay tuned to this blog and the GTAC website for application information and opportunities to present at GTAC. Subscribing to this blog is the best way to get notified. We're looking forward to seeing you there!  <br /><br />]]></description>
				<content:encoded><![CDATA[<i>Posted by Anthony Vallone on behalf of the GTAC Committee</i><br /><br />If you're looking for a place to discuss the latest innovations in test automation, then charge your tablets and pack your <a href="http://en.wikipedia.org/wiki/Wellington_boot">gumboots</a> - the  eighth <a href="https://developers.google.com/gtac/">GTAC</a> (Google Test Automation Conference) will be held on October 28-29, 2014 at Google Kirkland! The Kirkland office is part of the <a href="http://www.google.com/about/careers/locations/seattle-kirkland/">Seattle/Kirkland campus</a> in beautiful Washington state. This campus forms our third largest engineering office in the USA.<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-6pFux0LhOmA/U49xL6rnkrI/AAAAAAAAAF8/E8uecMVaSio/s1600/GTAC+2014+logo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-6pFux0LhOmA/U49xL6rnkrI/AAAAAAAAAF8/E8uecMVaSio/s1600/GTAC+2014+logo.png" height="200" width="200" /></a></div><br /><br />GTAC is a periodic conference hosted by Google, bringing together engineers from industry and academia to discuss advances in test automation and the test engineering computer science field. It’s a great opportunity to present, learn, and challenge modern testing technologies and strategies.  <br /><br />You can browse the presentation abstracts, slides, and videos from last year on the <a href="https://developers.google.com/google-test-automation-conference/2013/">GTAC 2013 page</a>. <br /><br />Stay tuned to this blog and the GTAC website for application information and opportunities to present at GTAC. Subscribing to this blog is the best way to get notified. We're looking forward to seeing you there!  <br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/gtac-2014-coming-to-seattlekirkland-in-october/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Testing on the Toilet:  Risk-Driven Testing</title>
		<link>https://googledata.org/google-testing/testing-on-the-toilet-risk-driven-testing/</link>
		<comments>https://googledata.org/google-testing/testing-on-the-toilet-risk-driven-testing/#comments</comments>
		<pubDate>Fri, 30 May 2014 23:10:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=5d168bea53db4e0194ac2a4295281b71</guid>
		<description><![CDATA[<i>by Peter Arrenbrecht</i><br /><br /><i>This article was adapted from a <a href="http://googletesting.blogspot.com/2007/01/introducing-testing-on-toilet.html">Google Testing on the Toilet</a> (TotT) episode. You can download a <a href="https://docs.google.com/document/d/1QfmhsvpiCx__rcU0sr03Lu1fM1yhE8P9atyTgeLbRAQ/edit?usp=sharing">printer-friendly version</a> of this TotT episode and post it in your office. </i><br /><br /><b><span>We are all conditioned to write tests</span></b> as we code: unit, functional, UI&#8212;the whole shebang. We are professionals, after all. Many of us like how small tests let us work quickly, and how larger tests inspire safety and closure. Or we may just anticipate flak during review. We are so used to these tests that often <b><span>we no longer question why we write them</span></b>. This can be wasteful and dangerous. <br /><br /><b><span>Tests are a means to an end:</span></b> To <span><b>reduce the key risks</b></span> of a project, and to <b><span>get the biggest bang for the buck</span></b>. This bang may not always come from the tests that standard practice has you write, or not even from tests at all. <br /><br />Two examples: <br /><br /><div><i>&#8220;We built a new debugging aid. We wrote unit, integration, and UI tests. We were ready to launch.&#8221;</i><br /><br />Outstanding practice. <b>Missing the mark.</b><br /><br />Our key risks were that we'd corrupt our data or bring down our servers for the sake of a debugging aid. None of the tests addressed this, but they gave a false sense of safety and &#8220;being done&#8221;.<br /><b>We stopped the launch.</b></div><br /><br /><div><i>&#8220;We wanted to turn down a feature, so we needed to alert affected users. Again we had unit and  integration tests, and even one expensive end-to-end test.&#8221;</i><br /><br />Standard practice. <b>Wasted effort.</b><br /><br />The alert was so critical it actually needed end-to-end coverage for all scenarios. But it would be live for only three releases. The cheapest effective test? Manual testing before each release.</div><br /><br /><b>A Better Approach: Risks First </b><br /><br />For every project or feature, <span><b>think about testing</b></span>. Brainstorm your key risks and your best options to reduce them. <span><b>Do this at the start</b></span> so you don't waste effort and can adapt your design. <b><span>Write them down</span></b> as a QA design so you can point to it in reviews and discussions. <br /><br />To be sure, <span><b>standard practice remains a good idea in most cases</b></span> (hence it&#8217;s standard). Small tests are cheap and speed up coding and maintenance, and larger tests safeguard core use-cases and integration. <br /><br /><span><b>Just remember</b></span>: Your tests are a means. <span><b>The bang is what counts</b></span>. It&#8217;s your job to <b><span>maximize it</span></b>. <br /><br />]]></description>
				<content:encoded><![CDATA[<i>by Peter Arrenbrecht</i><br /><br /><i>This article was adapted from a <a href="http://googletesting.blogspot.com/2007/01/introducing-testing-on-toilet.html">Google Testing on the Toilet</a> (TotT) episode. You can download a <a href="https://docs.google.com/document/d/1QfmhsvpiCx__rcU0sr03Lu1fM1yhE8P9atyTgeLbRAQ/edit?usp=sharing">printer-friendly version</a> of this TotT episode and post it in your office. </i><br /><br /><b><span style="color: #990000;">We are all conditioned to write tests</span></b> as we code: unit, functional, UI—the whole shebang. We are professionals, after all. Many of us like how small tests let us work quickly, and how larger tests inspire safety and closure. Or we may just anticipate flak during review. We are so used to these tests that often <b><span style="color: #990000;">we no longer question why we write them</span></b>. This can be wasteful and dangerous. <br /><br /><b><span style="color: #990000;">Tests are a means to an end:</span></b> To <span style="color: #990000;"><b>reduce the key risks</b></span> of a project, and to <b><span style="color: #990000;">get the biggest bang for the buck</span></b>. This bang may not always come from the tests that standard practice has you write, or not even from tests at all. <br /><br />Two examples: <br /><br /><div style="background: #fef2cc; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;"><i>“We built a new debugging aid. We wrote unit, integration, and UI tests. We were ready to launch.”</i><br /><br />Outstanding practice. <b>Missing the mark.</b><br /><br />Our key risks were that we'd corrupt our data or bring down our servers for the sake of a debugging aid. None of the tests addressed this, but they gave a false sense of safety and “being done”.<br /><b>We stopped the launch.</b></div><br /><br /><div style="background: #fef2cc; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;"><i>“We wanted to turn down a feature, so we needed to alert affected users. Again we had unit and  integration tests, and even one expensive end-to-end test.”</i><br /><br />Standard practice. <b>Wasted effort.</b><br /><br />The alert was so critical it actually needed end-to-end coverage for all scenarios. But it would be live for only three releases. The cheapest effective test? Manual testing before each release.</div><br /><br /><b>A Better Approach: Risks First </b><br /><br />For every project or feature, <span style="color: #990000;"><b>think about testing</b></span>. Brainstorm your key risks and your best options to reduce them. <span style="color: #990000;"><b>Do this at the start</b></span> so you don't waste effort and can adapt your design. <b><span style="color: #990000;">Write them down</span></b> as a QA design so you can point to it in reviews and discussions. <br /><br />To be sure, <span style="color: #990000;"><b>standard practice remains a good idea in most cases</b></span> (hence it’s standard). Small tests are cheap and speed up coding and maintenance, and larger tests safeguard core use-cases and integration. <br /><br /><span style="color: #990000;"><b>Just remember</b></span>: Your tests are a means. <span style="color: #990000;"><b>The bang is what counts</b></span>. It’s your job to <b><span style="color: #990000;">maximize it</span></b>. <br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/testing-on-the-toilet-risk-driven-testing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Testing on the Toilet: Effective Testing</title>
		<link>https://googledata.org/google-testing/testing-on-the-toilet-effective-testing/</link>
		<comments>https://googledata.org/google-testing/testing-on-the-toilet-effective-testing/#comments</comments>
		<pubDate>Wed, 07 May 2014 17:10:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=9a052769c5e314fd0b62e7e35de40c01</guid>
		<description><![CDATA[<i>by Rich Martin, Zurich </i><br /><i><br /></i><i>This article was adapted from a <a href="http://googletesting.blogspot.com/2007/01/introducing-testing-on-toilet.html">Google Testing on the Toilet</a> (TotT) episode. You can download a <a href="https://docs.google.com/document/d/1pb8AvYvshNRAP4x2skdd4fc0U2reCBxsMlccwEdFlFs/edit?usp=sharing">printer-friendly version</a> of this TotT episode and post it in your office. </i><br /><br /><br />Whether we are writing an individual unit test or designing a product&#8217;s entire testing process, it is important to take a step back and think about <span><b>how effective are our tests at detecting and reporting bugs in our code</b></span>. To be effective, there are <b><span>three important qualities</span></b> that every test should try to maximize: <br /><br /><b>Fidelity </b><br /><br />When the code under test is broken, the test fails. <b><span>A high&#173;-fidelity test is one which is very sensitive to defects in the code under test</span></b>, helping to prevent bugs from creeping into the code. <br /><br />Maximize fidelity by ensuring that your tests cover all the paths through your code and include all relevant assertions on the expected state. <br /><br /><b>Resilience </b><br /><br />A test shouldn&#8217;t fail if the code under test isn&#8217;t defective. <b><span>A resilient test is one that only fails when a breaking change is made to the code under test.</span></b> Refactorings and other non-&#173;breaking changes to the code under test can be made without needing to modify the test, reducing the cost of maintaining the tests. <br /><br />Maximize resilience by only testing the exposed API of the code under test&#894; avoid reaching into internals. Favor stubs and fakes over mocks&#894; don't verify interactions with dependencies unless it is that interaction that you are explicitly validating. A flaky test obviously has very low resilience. <br /><br /><b>Precision </b><br /><br />When a test fails, <b><span>a high&#173;-precision test tells you exactly where the defect lies</span></b>. A well&#173;-written unit test can tell you exactly which line of code is at fault. Poorly written tests (especially large end-to-end tests) often exhibit very low precision, telling you that something is broken but not where. <br /><br />Maximize precision by keeping your tests small and tightly &#173;focused. Choose descriptive method names that convey exactly what the test is validating. For system integration tests, validate state at every boundary. <br /><br />These three qualities are often in tension with each other. It's easy to write a highly resilient test (the empty test, for example), but writing a test that is both highly resilient and high&#173;-fidelity is hard. <b><span>As you design and write tests, use these qualities as a framework to guide your implementation</span></b>. <br /><br />]]></description>
				<content:encoded><![CDATA[<i>by Rich Martin, Zurich </i><br /><i><br /></i><i>This article was adapted from a <a href="http://googletesting.blogspot.com/2007/01/introducing-testing-on-toilet.html">Google Testing on the Toilet</a> (TotT) episode. You can download a <a href="https://docs.google.com/document/d/1pb8AvYvshNRAP4x2skdd4fc0U2reCBxsMlccwEdFlFs/edit?usp=sharing">printer-friendly version</a> of this TotT episode and post it in your office. </i><br /><br /><br />Whether we are writing an individual unit test or designing a product’s entire testing process, it is important to take a step back and think about <span style="color: #660000;"><b>how effective are our tests at detecting and reporting bugs in our code</b></span>. To be effective, there are <b><span style="color: #660000;">three important qualities</span></b> that every test should try to maximize: <br /><br /><b>Fidelity </b><br /><br />When the code under test is broken, the test fails. <b><span style="color: #660000;">A high­-fidelity test is one which is very sensitive to defects in the code under test</span></b>, helping to prevent bugs from creeping into the code. <br /><br />Maximize fidelity by ensuring that your tests cover all the paths through your code and include all relevant assertions on the expected state. <br /><br /><b>Resilience </b><br /><br />A test shouldn’t fail if the code under test isn’t defective. <b><span style="color: #660000;">A resilient test is one that only fails when a breaking change is made to the code under test.</span></b> Refactorings and other non-­breaking changes to the code under test can be made without needing to modify the test, reducing the cost of maintaining the tests. <br /><br />Maximize resilience by only testing the exposed API of the code under test; avoid reaching into internals. Favor stubs and fakes over mocks; don't verify interactions with dependencies unless it is that interaction that you are explicitly validating. A flaky test obviously has very low resilience. <br /><br /><b>Precision </b><br /><br />When a test fails, <b><span style="color: #660000;">a high­-precision test tells you exactly where the defect lies</span></b>. A well­-written unit test can tell you exactly which line of code is at fault. Poorly written tests (especially large end-to-end tests) often exhibit very low precision, telling you that something is broken but not where. <br /><br />Maximize precision by keeping your tests small and tightly ­focused. Choose descriptive method names that convey exactly what the test is validating. For system integration tests, validate state at every boundary. <br /><br />These three qualities are often in tension with each other. It's easy to write a highly resilient test (the empty test, for example), but writing a test that is both highly resilient and high­-fidelity is hard. <b><span style="color: #660000;">As you design and write tests, use these qualities as a framework to guide your implementation</span></b>. <br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/testing-on-the-toilet-effective-testing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Testing on the Toilet: Test Behaviors, Not Methods</title>
		<link>https://googledata.org/google-testing/testing-on-the-toilet-test-behaviors-not-methods/</link>
		<comments>https://googledata.org/google-testing/testing-on-the-toilet-test-behaviors-not-methods/#comments</comments>
		<pubDate>Mon, 14 Apr 2014 21:25:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=e1dca3362eb6cf8838ecbcd2f3ffb1e7</guid>
		<description><![CDATA[<i>by Erik Kuefler </i><br /><br /><i>This article was adapted from a <a href="http://googletesting.blogspot.com/2007/01/introducing-testing-on-toilet.html">Google Testing on the Toilet</a> (TotT) episode. You can download a <a href="https://docs.google.com/document/d/1W3BQgIYWZ-glc5kxvFGVE28uu4GAodAU1LU9-r4qwIs/edit?usp=sharing">printer-friendly version</a> of this TotT episode and post it in your office. </i><br /><br />After writing a method, it's easy to write just one test that verifies everything the method does. But <span><b>it can be harmful to think that tests and public methods should have a 1:1 relationship</b></span>. What we really want to test are behaviors, where a single method can exhibit many behaviors, and a single behavior sometimes spans across multiple methods. <br /><br />Let's take a look at a bad test that verifies an entire method: <br /><br /><pre>@Test <span>public</span> <span>void</span> testProcessTransaction() {<br />  User user = newUserWithBalance(LOW_BALANCE_THRESHOLD.plus(dollars(2));<br />  transactionProcessor.processTransaction(<br />      user,<br /><span>new</span> Transaction(<span>"Pile of Beanie Babies"</span>, dollars(3)));<br />  assertContains(<span>"You bought a Pile of Beanie Babies"</span>, ui.getText());<br />  assertEquals(1, user.getEmails().size());<br />  assertEquals(<span>"Your balance is low"</span>, user.getEmails().get(0).getSubject());<br />}<br /></pre><br />Displaying the name of the purchased item and sending an email about the balance being low are two separate behaviors, but this test looks at both of those behaviors together just because they happen to be triggered by the same method. <span><b>Tests like this very often become massive and difficult to maintain over time as additional behaviors keep getting added in</b></span>&#8212;eventually it will be very hard to tell which parts of the input are responsible for which assertions. The fact that the test's name is a direct mirror of the method's name is a bad sign.  <br /><br /><b><span>It's a much better idea to use separate tests to verify separate behaviors</span></b>: <br /><br /><pre>@Test <span>public</span> <span>void</span> testProcessTransaction_displaysNotification() {<br />  transactionProcessor.processTransaction(<br /><span>new</span> User(), <span>new</span> Transaction(<span>"Pile of Beanie Babies"</span>));<br />  assertContains(<span>"You bought a Pile of Beanie Babies"</span>, ui.getText());<br />}<br />@Test <span>public</span> <span>void</span> testProcessTransaction_sendsEmailWhenBalanceIsLow() {<br />  User user = newUserWithBalance(LOW_BALANCE_THRESHOLD.plus(dollars(2));<br />  transactionProcessor.processTransaction(<br />      user,<br /><span>new</span> Transaction(dollars(3)));<br />  assertEquals(1, user.getEmails().size());<br />  assertEquals(<span>"Your balance is low"</span>, user.getEmails().get(0).getSubject());<br />}<br /></pre><br />Now, when someone adds a new behavior, they will write a new test for that behavior. Each test will remain focused and easy to understand, no matter how many behaviors are added. <b><span>This will make your tests more resilient since adding new behaviors is unlikely to break the existing tests, and clearer since each test contains code to exercise only one behavior</span></b>. <br /><br />]]></description>
				<content:encoded><![CDATA[<i>by Erik Kuefler </i><br /><br /><i>This article was adapted from a <a href="http://googletesting.blogspot.com/2007/01/introducing-testing-on-toilet.html">Google Testing on the Toilet</a> (TotT) episode. You can download a <a href="https://docs.google.com/document/d/1W3BQgIYWZ-glc5kxvFGVE28uu4GAodAU1LU9-r4qwIs/edit?usp=sharing">printer-friendly version</a> of this TotT episode and post it in your office. </i><br /><br />After writing a method, it's easy to write just one test that verifies everything the method does. But <span style="color: purple;"><b>it can be harmful to think that tests and public methods should have a 1:1 relationship</b></span>. What we really want to test are behaviors, where a single method can exhibit many behaviors, and a single behavior sometimes spans across multiple methods. <br /><br />Let's take a look at a bad test that verifies an entire method: <br /><br /><pre style="background: #f0f0f0; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;">@Test <span style="color: #0433ff;">public</span> <span style="color: #0433ff;">void</span> testProcessTransaction() {<br />  User user = newUserWithBalance(LOW_BALANCE_THRESHOLD.plus(dollars(2));<br />  transactionProcessor.processTransaction(<br />      user,<br />      <span style="color: #0433ff;">new</span> Transaction(<span style="color: #ff2600;">"Pile of Beanie Babies"</span>, dollars(3)));<br />  assertContains(<span style="color: #ff2600;">"You bought a Pile of Beanie Babies"</span>, ui.getText());<br />  assertEquals(1, user.getEmails().size());<br />  assertEquals(<span style="color: #ff2600;">"Your balance is low"</span>, user.getEmails().get(0).getSubject());<br />}<br /></pre><br />Displaying the name of the purchased item and sending an email about the balance being low are two separate behaviors, but this test looks at both of those behaviors together just because they happen to be triggered by the same method. <span style="color: purple;"><b>Tests like this very often become massive and difficult to maintain over time as additional behaviors keep getting added in</b></span>—eventually it will be very hard to tell which parts of the input are responsible for which assertions. The fact that the test's name is a direct mirror of the method's name is a bad sign.  <br /><br /><b><span style="color: purple;">It's a much better idea to use separate tests to verify separate behaviors</span></b>: <br /><br /><pre style="background: #f0f0f0; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;">@Test <span style="color: #0433ff;">public</span> <span style="color: #0433ff;">void</span> testProcessTransaction_displaysNotification() {<br />  transactionProcessor.processTransaction(<br />      <span style="color: #0433ff;">new</span> User(), <span style="color: #0433ff;">new</span> Transaction(<span style="color: #ff2600;">"Pile of Beanie Babies"</span>));<br />  assertContains(<span style="color: #ff2600;">"You bought a Pile of Beanie Babies"</span>, ui.getText());<br />}<br />@Test <span style="color: #0433ff;">public</span> <span style="color: #0433ff;">void</span> testProcessTransaction_sendsEmailWhenBalanceIsLow() {<br />  User user = newUserWithBalance(LOW_BALANCE_THRESHOLD.plus(dollars(2));<br />  transactionProcessor.processTransaction(<br />      user,<br />      <span style="color: #0433ff;">new</span> Transaction(dollars(3)));<br />  assertEquals(1, user.getEmails().size());<br />  assertEquals(<span style="color: #ff2600;">"Your balance is low"</span>, user.getEmails().get(0).getSubject());<br />}<br /></pre><br />Now, when someone adds a new behavior, they will write a new test for that behavior. Each test will remain focused and easy to understand, no matter how many behaviors are added. <b><span style="color: purple;">This will make your tests more resilient since adding new behaviors is unlikely to break the existing tests, and clearer since each test contains code to exercise only one behavior</span></b>. <br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/testing-on-the-toilet-test-behaviors-not-methods/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>The *Real* Test Driven Development</title>
		<link>https://googledata.org/google-testing/the-real-test-driven-development/</link>
		<comments>https://googledata.org/google-testing/the-real-test-driven-development/#comments</comments>
		<pubDate>Tue, 01 Apr 2014 09:00:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=6a38d0ae3e632f0524c1dbb34d168b98</guid>
		<description><![CDATA[<i></i><br /><div><span><b>Update: APRIL FOOLS!</b></span></div><div><br /></div><i><br /></i><i>by Kaue Silveira </i><br /><br />Here at Google, we invest heavily in development productivity research. In fact, our TDD research group now occupies nearly an entire building of the <a href="http://en.wikipedia.org/wiki/Googleplex">Googleplex</a>. The group has been working hard to minimize the development cycle time, and we&#8217;d like to share some of the amazing progress they&#8217;ve made. <br /><br /><b>The Concept </b><br /><br />In the ways of old, it used to be that people wrote tests for their existing code. This was changed by TDD (Test-driven Development), where one would write the test first and then write the code to satisfy it. The TDD research group didn&#8217;t think this was enough and wanted to elevate the humble test to the next level. We are pleased to announce the <b>Real</b> TDD, our latest innovation in the <a href="http://en.wikipedia.org/wiki/Program_synthesis">Program Synthesis</a> field, where you write only the tests and have the computer write the code for you!<br /><br />The following graph shows how the number of tests created by a small feature team grew since they started using this tool towards the end of 2013. Over the last 2 quarters, more than 89% of this team&#8217;s production code was written by the tool! <br /><br /><div><a href="http://2.bp.blogspot.com/-L7u928SyPZo/UzYwxxJnJ_I/AAAAAAAAAFk/4NPxE5h691o/s1600/image.png"><img border="0" src="http://2.bp.blogspot.com/-L7u928SyPZo/UzYwxxJnJ_I/AAAAAAAAAFk/4NPxE5h691o/s1600/image.png" height="393" width="640"></a></div><b>See it in action: </b><br /><br />Test written by a Software Engineer: <br /><br /><pre><span>class</span> LinkGeneratorTest(googletest.TestCase):<br /><br /><span>def</span> setUp(<span>self</span>):<br /><span>self</span>.generator = link_generator.LinkGenerator()<br /><br /><span>def</span> testGetLinkFromIDs(<span>self</span>):<br />    expected = (<span>'https://frontend.google.com/advancedSearchResults?'</span><br /><span>'s.op=ALL&#38;s.r0.field=ID&#38;s.r0.val=1288585+1310696+1346270+'</span>)<br />    actual = <span>self</span>.generator.GetLinkFromIDs(set((1346270, 1310696, 1288585)))<br /><span>self</span>.assertEqual(expected, actual)</pre><br />Code created by our tool: <br /><br /><pre><span>import</span> urllib<br /><br /><span>class</span> LinkGenerator(object):<br /><br />  _URL = (<br /><span>'https://frontend.google.com/advancedSearchResults?'</span><br /><span>'s.op=ALL&#38;s.r0.field=ID&#38;s.r0.val='</span>)<br /><br /><span>def</span> GetLinkFromIDs(<span>self</span>, ids):<br />    result = []<br /><span>for</span> id <span>in</span> sorted(ids):<br />      result.append(<span>'%s '</span> % id)<br /><span>return</span> <span>self</span>._URL + urllib.quote_plus(<span>''</span>.join(result))<br /></pre><br />Note that the tool is smart enough to not generate the obvious implementation of returning a constant string, but instead it correctly abstracts and generalizes the relation between inputs and outputs. It becomes smarter at every use and it&#8217;s behaving more and more like a human programmer every day. We once saw a comment in the generated code that said "I need some coffee". <br /><br /><b>How does it work? </b><br /><br />We&#8217;ve trained the <a href="http://en.wikipedia.org/wiki/Google_Brain">Google Brain</a> with billions of lines of open-source software to learn about coding patterns and how product code correlates with test code. Its accuracy is further improved by using  <a href="http://en.wikipedia.org/wiki/Type_inference">Type Inference</a> to infer types from code and the <a href="https://www.youtube.com/watch?v=h0OkptwfX4g&#38;feature=youtu.be&#38;t=21m30s">Girard-Reynolds Isomorphism</a> to infer code from types. <br /><br />The tool runs every time your unit test is saved, and it uses the learned model to guide a backtracking search for a code snippet that satisfies all assertions in the test. It provides sub-second responses for 99.5% of the cases (as shown in the following graph), thanks to millions of pre-computed assertion-snippet pairs stored in <a href="http://en.wikipedia.org/wiki/Spanner_(database)">Spanner</a> for global low-latency access. <br /><br /><div><a href="http://2.bp.blogspot.com/-nH9kf2nDmPk/UzYxCZvYD0I/AAAAAAAAAFs/bhiaJW-qwjU/s1600/image+(1).png"><img border="0" src="http://2.bp.blogspot.com/-nH9kf2nDmPk/UzYxCZvYD0I/AAAAAAAAAFs/bhiaJW-qwjU/s1600/image+(1).png" height="394" width="640"></a></div><br /><br /><b>How can I use it? </b><br /><br />We will offer a free (rate-limited) service that everyone can use, once we have sorted out the legal issues regarding the possibility of mixing code snippets originating from open-source projects with different licenses (e.g., <a href="http://en.wikipedia.org/wiki/GNU_General_Public_License">GPL-licensed</a> tests will simply refuse to pass <a href="http://en.wikipedia.org/wiki/BSD_licenses">BSD-licensed</a> code snippets). If you would like to try our alpha release before the public launch, leave us a comment! <br /><br />]]></description>
				<content:encoded><![CDATA[<i></i><br /><div style="text-align: center;"><span style="color: red;"><b>Update: APRIL FOOLS!</b></span></div><div><br /></div><i><br /></i><i>by Kaue Silveira </i><br /><br />Here at Google, we invest heavily in development productivity research. In fact, our TDD research group now occupies nearly an entire building of the <a href="http://en.wikipedia.org/wiki/Googleplex">Googleplex</a>. The group has been working hard to minimize the development cycle time, and we’d like to share some of the amazing progress they’ve made. <br /><br /><b>The Concept </b><br /><br />In the ways of old, it used to be that people wrote tests for their existing code. This was changed by TDD (Test-driven Development), where one would write the test first and then write the code to satisfy it. The TDD research group didn’t think this was enough and wanted to elevate the humble test to the next level. We are pleased to announce the <b>Real</b> TDD, our latest innovation in the <a href="http://en.wikipedia.org/wiki/Program_synthesis">Program Synthesis</a> field, where you write only the tests and have the computer write the code for you!<br /><br />The following graph shows how the number of tests created by a small feature team grew since they started using this tool towards the end of 2013. Over the last 2 quarters, more than 89% of this team’s production code was written by the tool! <br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-L7u928SyPZo/UzYwxxJnJ_I/AAAAAAAAAFk/4NPxE5h691o/s1600/image.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-L7u928SyPZo/UzYwxxJnJ_I/AAAAAAAAAFk/4NPxE5h691o/s1600/image.png" height="393" width="640" /></a></div><b>See it in action: </b><br /><br />Test written by a Software Engineer: <br /><br /><pre style="background: #f0f0f0; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;"><span style="color: #0433ff;">class</span> LinkGeneratorTest(googletest.TestCase):<br /><br />  <span style="color: #0433ff;">def</span> setUp(<span style="color: #0433ff;">self</span>):<br />    <span style="color: #0433ff;">self</span>.generator = link_generator.LinkGenerator()<br /><br />  <span style="color: #0433ff;">def</span> testGetLinkFromIDs(<span style="color: #0433ff;">self</span>):<br />    expected = (<span style="color: #ff2600;">'https://frontend.google.com/advancedSearchResults?'</span><br />                <span style="color: #ff2600;">'s.op=ALL&amp;s.r0.field=ID&amp;s.r0.val=1288585+1310696+1346270+'</span>)<br />    actual = <span style="color: #0433ff;">self</span>.generator.GetLinkFromIDs(set((1346270, 1310696, 1288585)))<br />    <span style="color: #0433ff;">self</span>.assertEqual(expected, actual)</pre><br />Code created by our tool: <br /><br /><pre style="background: #f0f0f0; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;"><span style="color: #0433ff;">import</span> urllib<br /><br /><span style="color: #0433ff;">class</span> LinkGenerator(object):<br /><br />  _URL = (<br />      <span style="color: #ff2600;">'https://frontend.google.com/advancedSearchResults?'</span><br />      <span style="color: #ff2600;">'s.op=ALL&amp;s.r0.field=ID&amp;s.r0.val='</span>)<br /><br />  <span style="color: #0433ff;">def</span> GetLinkFromIDs(<span style="color: #0433ff;">self</span>, ids):<br />    result = []<br />    <span style="color: #0433ff;">for</span> id <span style="color: #0433ff;">in</span> sorted(ids):<br />      result.append(<span style="color: #ff2600;">'%s '</span> % id)<br />    <span style="color: #0433ff;">return</span> <span style="color: #0433ff;">self</span>._URL + urllib.quote_plus(<span style="color: #ff2600;">''</span>.join(result))<br /></pre><br />Note that the tool is smart enough to not generate the obvious implementation of returning a constant string, but instead it correctly abstracts and generalizes the relation between inputs and outputs. It becomes smarter at every use and it’s behaving more and more like a human programmer every day. We once saw a comment in the generated code that said "I need some coffee". <br /><br /><b>How does it work? </b><br /><br />We’ve trained the <a href="http://en.wikipedia.org/wiki/Google_Brain">Google Brain</a> with billions of lines of open-source software to learn about coding patterns and how product code correlates with test code. Its accuracy is further improved by using  <a href="http://en.wikipedia.org/wiki/Type_inference">Type Inference</a> to infer types from code and the <a href="https://www.youtube.com/watch?v=h0OkptwfX4g&amp;feature=youtu.be&amp;t=21m30s">Girard-Reynolds Isomorphism</a> to infer code from types. <br /><br />The tool runs every time your unit test is saved, and it uses the learned model to guide a backtracking search for a code snippet that satisfies all assertions in the test. It provides sub-second responses for 99.5% of the cases (as shown in the following graph), thanks to millions of pre-computed assertion-snippet pairs stored in <a href="http://en.wikipedia.org/wiki/Spanner_(database)">Spanner</a> for global low-latency access. <br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-nH9kf2nDmPk/UzYxCZvYD0I/AAAAAAAAAFs/bhiaJW-qwjU/s1600/image+(1).png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-nH9kf2nDmPk/UzYxCZvYD0I/AAAAAAAAAFs/bhiaJW-qwjU/s1600/image+(1).png" height="394" width="640" /></a></div><br /><br /><b>How can I use it? </b><br /><br />We will offer a free (rate-limited) service that everyone can use, once we have sorted out the legal issues regarding the possibility of mixing code snippets originating from open-source projects with different licenses (e.g., <a href="http://en.wikipedia.org/wiki/GNU_General_Public_License">GPL-licensed</a> tests will simply refuse to pass <a href="http://en.wikipedia.org/wiki/BSD_licenses">BSD-licensed</a> code snippets). If you would like to try our alpha release before the public launch, leave us a comment! <br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/the-real-test-driven-development/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Testing on the Toilet: What Makes a Good Test?</title>
		<link>https://googledata.org/google-testing/testing-on-the-toilet-what-makes-a-good-test/</link>
		<comments>https://googledata.org/google-testing/testing-on-the-toilet-what-makes-a-good-test/#comments</comments>
		<pubDate>Tue, 18 Mar 2014 22:10:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=f6cef583b1900b373dff33de2ee22942</guid>
		<description><![CDATA[<i>by Erik Kuefler </i><br /><br /><i>This article was adapted from a <a href="http://googletesting.blogspot.com/2007/01/introducing-testing-on-toilet.html">Google Testing on the Toilet</a> (TotT) episode. You can download a <a href="https://docs.google.com/document/d/1C51MIOYAy699S5Sm2WRDsCnutUIQyi7Tzw5EbhRo_Mo/edit?usp=sharing">printer-friendly version</a> of this TotT episode and post it in your office. </i><br /><br />Unit tests are important tools for verifying that our code is correct. But <span><b>writing good tests is about much more than just verifying correctness</b></span> &#8212; a good unit test should exhibit several other properties in order to be readable and maintainable. <br /><br />One property of a good test is clarity. <b><span>Clarity means that a test should serve as readable documentation for humans, describing the code being tested in terms of its public APIs.</span></b> Tests shouldn't refer directly to implementation details. The names of a class's tests should say everything the class does, and the tests themselves should serve as examples for how to use the class. <br /><br />Two more important properties are completeness and conciseness. <b><span>A test is complete when its body contains all of the information you need to understand it, and concise when it doesn't contain any other distracting information.</span></b> This test fails on both counts: <br /><br /><pre>@Test <span>public</span> <span>void</span> shouldPerformAddition() {<br />  Calculator <b>calculator</b> = <span>new</span> Calculator(<span>new</span> RoundingStrategy(), <br /><span>"unused"</span>, ENABLE_COSIN_FEATURE, 0.01, calculusEngine, <span>false</span>);<br /><span>int</span> <b>result</b> = <b>calculator</b>.doComputation(makeTestComputation());<br />  assertEquals(<b>5</b>, <b>result</b>); <span>// Where did this number come from?</span><br />}</pre><br />Lots of distracting information is being passed to the constructor, and the important parts are hidden off in a helper method. The test can be made more complete by clarifying the purpose of the helper method, and more concise by using another helper to hide the irrelevant details of constructing the calculator: <br /><br /><pre>@Test <span>public</span> <span>void</span> shouldPerformAddition() {<br />  Calculator <b>calculator</b> = newCalculator();<br /><span>int</span> <b>result</b> = <b>calculator</b>.doComputation(makeAdditionComputation(<b>2</b>, <b>3</b>));<br />  assertEquals(<b>5</b>, <b>result</b>);<br />}</pre><br />One final property of a good test is resilience. Once written, a <b><span>resilient test doesn't have to change unless the purpose or behavior of the class being tested changes</span></b>. Adding new behavior should only require adding new tests, not changing old ones. The original test above isn't resilient since you'll have to update it (and probably dozens of other tests!) whenever you add a new irrelevant constructor parameter. Moving these details into the helper method solved this problem. <br /><br />]]></description>
				<content:encoded><![CDATA[<i>by Erik Kuefler </i><br /><br /><i>This article was adapted from a <a href="http://googletesting.blogspot.com/2007/01/introducing-testing-on-toilet.html">Google Testing on the Toilet</a> (TotT) episode. You can download a <a href="https://docs.google.com/document/d/1C51MIOYAy699S5Sm2WRDsCnutUIQyi7Tzw5EbhRo_Mo/edit?usp=sharing">printer-friendly version</a> of this TotT episode and post it in your office. </i><br /><br />Unit tests are important tools for verifying that our code is correct. But <span style="color: purple;"><b>writing good tests is about much more than just verifying correctness</b></span> — a good unit test should exhibit several other properties in order to be readable and maintainable. <br /><br />One property of a good test is clarity. <b><span style="color: purple;">Clarity means that a test should serve as readable documentation for humans, describing the code being tested in terms of its public APIs.</span></b> Tests shouldn't refer directly to implementation details. The names of a class's tests should say everything the class does, and the tests themselves should serve as examples for how to use the class. <br /><br />Two more important properties are completeness and conciseness. <b><span style="color: purple;">A test is complete when its body contains all of the information you need to understand it, and concise when it doesn't contain any other distracting information.</span></b> This test fails on both counts: <br /><br /><pre style="background: #f9f9f9; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;">@Test <span style="color: #0433ff;">public</span> <span style="color: #0433ff;">void</span> shouldPerformAddition() {<br />  Calculator <b>calculator</b> = <span style="color: #0433ff;">new</span> Calculator(<span style="color: #0433ff;">new</span> RoundingStrategy(), <br />      <span style="color: #ff2600;">"unused"</span>, ENABLE_COSIN_FEATURE, 0.01, calculusEngine, <span style="color: #0433ff;">false</span>);<br />  <span style="color: #0433ff;">int</span> <b>result</b> = <b>calculator</b>.doComputation(makeTestComputation());<br />  assertEquals(<b>5</b>, <b>result</b>); <span style="color: #4f8f00;">// Where did this number come from?</span><br />}</pre><br />Lots of distracting information is being passed to the constructor, and the important parts are hidden off in a helper method. The test can be made more complete by clarifying the purpose of the helper method, and more concise by using another helper to hide the irrelevant details of constructing the calculator: <br /><br /><pre style="background: #f9f9f9; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;">@Test <span style="color: #0433ff;">public</span> <span style="color: #0433ff;">void</span> shouldPerformAddition() {<br />  Calculator <b>calculator</b> = newCalculator();<br />  <span style="color: #0433ff;">int</span> <b>result</b> = <b>calculator</b>.doComputation(makeAdditionComputation(<b>2</b>, <b>3</b>));<br />  assertEquals(<b>5</b>, <b>result</b>);<br />}</pre><br />One final property of a good test is resilience. Once written, a <b><span style="color: purple;">resilient test doesn't have to change unless the purpose or behavior of the class being tested changes</span></b>. Adding new behavior should only require adding new tests, not changing old ones. The original test above isn't resilient since you'll have to update it (and probably dozens of other tests!) whenever you add a new irrelevant constructor parameter. Moving these details into the helper method solved this problem. <br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/testing-on-the-toilet-what-makes-a-good-test/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>When/how to use Mockito Answer</title>
		<link>https://googledata.org/google-testing/whenhow-to-use-mockito-answer/</link>
		<comments>https://googledata.org/google-testing/whenhow-to-use-mockito-answer/#comments</comments>
		<pubDate>Mon, 03 Mar 2014 21:19:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=a243a677e729a4a9b268a158e02d6af8</guid>
		<description><![CDATA[<i>by Hongfei Ding, Software Engineer, Shanghai </i><br /><br /><a href="https://code.google.com/p/mockito/">Mockito</a> is a popular open source Java testing framework that allows the creation of mock objects. For example, we have the below interface used in our SUT (System Under Test):<br /><pre><span>interface</span> Service {<br />  Data get();<br />}</pre><br />In our test, normally we want to fake the <span><b>Service</b></span>&#8217;s behavior to return canned data, so that the unit test can focus on testing the code that interacts with the <span><b>Service</b></span>. We use <span><b>when-return</b></span> clause to stub a method.<br /><pre>when(service.get()).thenReturn(cannedData);</pre><br />But sometimes you need mock object behavior that's too complex for <span><b>when-return</b></span>. An <a href="http://docs.mockito.googlecode.com/hg/latest/org/mockito/stubbing/Answer.html"><span>Answer</span></a> object can be a clean way to do this once you get the syntax right.<br /><br />A common usage of <span><b>Answer</b></span> is to <b>stub asynchronous methods that have callbacks</b>. For example, we have mocked the interface below:<br /><pre><span>interface</span> Service {<br /><span>void</span> get(Callback callback);<br />}</pre><br />Here you&#8217;ll find that <span><b>when-return</b></span> is not that helpful anymore. <span><b>Answer</b></span> is the replacement. For example, we can <b>emulate a success</b> by calling the <span><b>onSuccess</b></span> function of the callback.<br /><pre>doAnswer(<span>new</span> Answer&#60;Void&#62;() {<br /><span>public</span> Void answer(InvocationOnMock invocation) {<br />       Callback callback = (Callback) invocation.getArguments()[0];<br />       callback.onSuccess(cannedData);<br /><span>return</span> null;<br />    }<br />}).when(service).get(any(Callback.<span>class</span>));</pre><br /><span><b>Answer</b></span> can also be used to <b>make smarter stubs for synchronous methods</b>. Smarter here means the stub can return a value depending on the input, rather than canned data. It&#8217;s sometimes quite useful. For example, we have mocked the <span><b>Translator</b></span>&#160;interface below:<br /><pre><span>interface</span> Translator {<br />  String translate(String msg);<br />}</pre><br />We might choose to mock <span><b>Translator</b></span> to return a constant string and then assert the result. However, that test is not thorough, because the input to the <span><b>translator</b></span>&#160;function has been ignored. To improve this, we might capture the input and do extra verification, but then we start to fall into the &#8220;<a href="http://googletesting.blogspot.tw/2013/03/testing-on-toilet-testing-state-vs.html">testing interaction rather than testing state</a>&#8221; trap.  <br /><br />A good usage of <span><b>Answer</b></span> is <b>to reverse the input message as a fake translation</b>. So that both things are assured by checking the result string: 1) <span><b>translate</b></span> has been invoked, 2) the <span><b>msg</b></span> being translated is correct. Notice that this time we&#8217;ve used <span><b>thenAnswer</b></span> syntax, a twin of <span><b>doAnswer</b></span>, for stubbing a non-void method.<br /><pre>when(translator.translate(any(String.<span>class</span>))).thenAnswer(reverseMsg())<br />...<br /><span>// extracted a method to put a descriptive name</span><br /><span>private</span> <span>static</span> Answer&#60;String&#62; reverseMsg() { <br /><span>return</span> <span>new</span> Answer&#60;String&#62;() {<br /><span>public</span> String answer(InvocationOnMock invocation) {<br /><span>return</span> reverseString((String) invocation.getArguments()[0]));<br />    }<br />  }<br />}</pre><br />Last but not least, if you find yourself writing many nontrivial <span><b>Answer</b></span>s, you should consider using a <a href="http://googletesting.blogspot.com/2013/06/testing-on-toilet-fake-your-way-to.html">fake</a> instead. <br /><br />]]></description>
				<content:encoded><![CDATA[<i>by Hongfei Ding, Software Engineer, Shanghai </i><br /><br /><a href="https://code.google.com/p/mockito/">Mockito</a> is a popular open source Java testing framework that allows the creation of mock objects. For example, we have the below interface used in our SUT (System Under Test):<br /><pre style="background: #f9f9f9; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;"><span style="color: #0433ff;">interface</span> Service {<br />  Data get();<br />}</pre><br />In our test, normally we want to fake the <span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>Service</b></span>’s behavior to return canned data, so that the unit test can focus on testing the code that interacts with the <span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>Service</b></span>. We use <span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>when-return</b></span> clause to stub a method.<br /><pre style="background: #f9f9f9; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;">when(service.get()).thenReturn(cannedData);</pre><br />But sometimes you need mock object behavior that's too complex for <span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>when-return</b></span>. An <a href="http://docs.mockito.googlecode.com/hg/latest/org/mockito/stubbing/Answer.html"><span style="font-family: Courier New, Courier, monospace;">Answer</span></a> object can be a clean way to do this once you get the syntax right.<br /><br />A common usage of <span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>Answer</b></span> is to <b>stub asynchronous methods that have callbacks</b>. For example, we have mocked the interface below:<br /><pre style="background: #f9f9f9; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;"><span style="color: #0433ff;">interface</span> Service {<br />  <span style="color: #0433ff;">void</span> get(Callback callback);<br />}</pre><br />Here you’ll find that <span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>when-return</b></span> is not that helpful anymore. <span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>Answer</b></span> is the replacement. For example, we can <b>emulate a success</b> by calling the <span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>onSuccess</b></span> function of the callback.<br /><pre style="background: #f9f9f9; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;">doAnswer(<span style="color: #0433ff;">new</span> Answer&lt;Void&gt;() {<br />    <span style="color: #0433ff;">public</span> Void answer(InvocationOnMock invocation) {<br />       Callback callback = (Callback) invocation.getArguments()[0];<br />       callback.onSuccess(cannedData);<br />       <span style="color: #0433ff;">return</span> null;<br />    }<br />}).when(service).get(any(Callback.<span style="color: #0433ff;">class</span>));</pre><br /><span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>Answer</b></span> can also be used to <b>make smarter stubs for synchronous methods</b>. Smarter here means the stub can return a value depending on the input, rather than canned data. It’s sometimes quite useful. For example, we have mocked the <span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>Translator</b></span>&nbsp;interface below:<br /><pre style="background: #f9f9f9; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;"><span style="color: #0433ff;">interface</span> Translator {<br />  String translate(String msg);<br />}</pre><br />We might choose to mock <span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>Translator</b></span> to return a constant string and then assert the result. However, that test is not thorough, because the input to the <span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>translator</b></span>&nbsp;function has been ignored. To improve this, we might capture the input and do extra verification, but then we start to fall into the “<a href="http://googletesting.blogspot.tw/2013/03/testing-on-toilet-testing-state-vs.html">testing interaction rather than testing state</a>” trap.  <br /><br />A good usage of <span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>Answer</b></span> is <b>to reverse the input message as a fake translation</b>. So that both things are assured by checking the result string: 1) <span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>translate</b></span> has been invoked, 2) the <span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>msg</b></span> being translated is correct. Notice that this time we’ve used <span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>thenAnswer</b></span> syntax, a twin of <span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>doAnswer</b></span>, for stubbing a non-void method.<br /><pre style="background: #f9f9f9; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;">when(translator.translate(any(String.<span style="color: #0433ff;">class</span>))).thenAnswer(reverseMsg())<br />...<br /><span style="color: #4f8f00;">// extracted a method to put a descriptive name</span><br /><span style="color: #0433ff;">private</span> <span style="color: #0433ff;">static</span> Answer&lt;String&gt; reverseMsg() { <br />  <span style="color: #0433ff;">return</span> <span style="color: #0433ff;">new</span> Answer&lt;String&gt;() {<br />    <span style="color: #0433ff;">public</span> String answer(InvocationOnMock invocation) {<br />       <span style="color: #0433ff;">return</span> reverseString((String) invocation.getArguments()[0]));<br />    }<br />  }<br />}</pre><br />Last but not least, if you find yourself writing many nontrivial <span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>Answer</b></span>s, you should consider using a <a href="http://googletesting.blogspot.com/2013/06/testing-on-toilet-fake-your-way-to.html">fake</a> instead. <br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/whenhow-to-use-mockito-answer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Minimizing Unreproducible Bugs</title>
		<link>https://googledata.org/google-testing/minimizing-unreproducible-bugs/</link>
		<comments>https://googledata.org/google-testing/minimizing-unreproducible-bugs/#comments</comments>
		<pubDate>Mon, 03 Feb 2014 19:23:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=1bfb81e6d0dcd91d07751b1497bd77a7</guid>
		<description><![CDATA[<div><a href="http://4.bp.blogspot.com/-W_7cqFXE2DA/Uu_ksr9HQOI/AAAAAAAAAFM/63eqQLF0cR8/s1600/cannot-repro.png"><img border="0" src="http://4.bp.blogspot.com/-W_7cqFXE2DA/Uu_ksr9HQOI/AAAAAAAAAFM/63eqQLF0cR8/s1600/cannot-repro.png" height="307" width="320"></a></div><br /><br /><i>by <a href="http://www.anthonysapps.com/anthony">Anthony Vallone</a></i><br /><br />Unreproducible bugs are the bane of my existence. Far too often, I find a bug, report it, and hear back that it&#8217;s not a bug because it can&#8217;t be reproduced. Of course, the bug is still there, waiting to prey on its next victim. These types of bugs can be very expensive due to increased investigation time and overall lifetime. They can also have a damaging effect on product perception when users reporting these bugs are effectively ignored. We should be doing more to prevent them. In this article, I&#8217;ll go over some obvious, and maybe not so obvious, development/testing guidelines that can reduce the likelihood of these bugs from occurring. <br /><br /><br /><b><span>Avoid and test for race conditions, deadlocks, timing issues, memory corruption, uninitialized memory access, memory leaks, and resource issues </span></b><br /><br />I am lumping together many bug types in this section, but they are all related somewhat by how we test for them and how disproportionately hard they are to reproduce and debug. The root cause and effect can be separated by milliseconds or hours, and stack traces might be nonexistent or misleading. A system may fail in strange ways when exposed to unusual traffic spikes or insufficient resources. Race conditions and deadlocks may only be discovered during unique traffic patterns or resource configurations. Timing issues may only be noticed when many components are integrated and their performance parameters and failure/retry/timeout delays create a chaotic system. Memory corruption or uninitialized memory access may go unnoticed for a large percentage of calls but become fatal for rare states. Memory leaks may be negligible unless the system is exposed to load for an extended period of time. <br /><br /><u>Guidelines for development: </u><br /><br /><ul><li>Simplify your synchronization logic. If it&#8217;s too hard to understand, it will be difficult to reproduce and debug complex concurrency problems. </li><li>Always obtain locks in the same order. This is a tried-and-true guideline to avoid deadlocks, but I still see code that breaks it periodically. Define an order for obtaining multiple locks and never change that order.  </li><li>Don&#8217;t optimize by creating many fine-grained locks, unless you have verified that they are needed. Extra locks increase concurrency complexity. </li><li>Avoid shared memory, unless you truly need it. Shared memory access is very easy to get wrong, and the bugs may be quite difficult to reproduce. </li></ul><br /><u>Guidelines for testing: </u><br /><br /><ul><li><a href="http://en.wikipedia.org/wiki/Stress_testing">Stress test</a> your system regularly. You don't want to be surprised by unexpected failures when your system is under heavy load.  </li><li>Test timeouts. Create tests that mock/fake dependencies to test timeout code. If your timeout code does something bad, it may cause a bug that only occurs under certain system conditions. </li><li>Test with debug and optimized builds. You may find that a well behaved debug build works fine, but the system fails in strange ways once optimized. </li><li>Test under constrained resources. Try reducing the number of data centers, machines, processes, threads, available disk space, or available memory. Also try simulating reduced network bandwidth. </li><li>Test for longevity. Some bugs require a long period of time to reveal themselves. For example, persistent data may become corrupt over time. </li><li>Use dynamic analysis tools like <a href="http://en.wikipedia.org/wiki/Memory_debugger">memory debuggers</a>, <a href="https://code.google.com/p/address-sanitizer/">ASan</a>, <a href="https://code.google.com/p/thread-sanitizer/">TSan</a>, and <a href="https://code.google.com/p/memory-sanitizer/wiki/MemorySanitizer">MSan</a> regularly. They can help identify many categories of unreproducible memory/threading issues. </li></ul><br /><br /><b><span>Enforce preconditions </span></b><br /><br />I&#8217;ve seen many well-meaning functions with a high tolerance for bad input. For example, consider this function: <br /><br /><pre><span>void</span> ScheduleEvent(<span>int</span> timeDurationMilliseconds) {<br /><span>if</span> (timeDurationMilliseconds &#60;= 0) {<br />    timeDurationMilliseconds = 1;<br />  }<br />  ...<br />}<br /></pre><br />This function is trying to help the calling code by adjusting the input to an acceptable value, but it may be doing damage by masking a bug. The calling code may be experiencing any number of problems described in this article, and passing garbage to this function will always work fine. The more functions that are written with this level of tolerance, the harder it is to trace back to the root cause, and the more likely it becomes that the end user will see garbage. Enforcing preconditions, for instance by using asserts, may actually cause a higher number of failures for new systems, but as systems mature, and many minor/major problems are identified early on, these checks can help improve long-term reliability. <br /><br /><u>Guidelines for development: </u><br /><br /><ul><li>Enforce preconditions in your functions unless you have a good reason not to. </li></ul><br /><br /><b><span>Use defensive programming </span></b><br /><br /><a href="http://en.wikipedia.org/wiki/Defensive_programming">Defensive programming</a> is another tried-and-true technique that is great at minimizing unreproducible bugs. If your code calls a dependency to do something, and that dependency quietly fails or returns garbage, how does your code handle it? You could test for situations like this via mocking or faking, but it&#8217;s even better to have your production code do sanity checking on its dependencies. For example: <br /><br /><pre><span>double</span> GetMonthlyLoanPayment() {<br /><span>double</span> rate = GetTodaysInterestRateFromExternalSystem();<br /><span>if</span> (rate &#60; 0.001 &#124;&#124; rate &#62; 0.5) {<br /><span>throw</span> BadInterestRate(rate);<br />  }<br />  ...<br />}<br /></pre><br /><u>Guidelines for development: </u><br /><br /><ul><li>When possible, use defensive programming to verify the work of your dependencies with known risks of failure like user-provided data, I/O operations, and RPC calls. </li></ul><br /><u>Guidelines for testing: </u><br /><br /><ul><li>Use <a href="http://en.wikipedia.org/wiki/Fuzz_testing">fuzz testing</a> to test your systems hardiness when enduring bad data. </li></ul><br /><br /><b><span>Don&#8217;t hide all errors from the user </span></b><br /><br />There has been a trend in recent years toward hiding failures from users at all costs. In many cases, it makes perfect sense, but in some, we have gone overboard. Code that is very quiet and permissive during minor failures will allow an uninformed user to continue working in a failed state. The software may ultimately reach a fatal tipping point, and all the error conditions that led to failure have been ignored. If the user doesn&#8217;t know about the prior errors, they will not be able to report them, and you may not be able to reproduce them. <br /><br /><u>Guidelines for development: </u><br /><br /><ul><li>Only hide errors from the user when you are certain that there is no impact to system state or the user. </li><li>Any error with impact to the user should be reported to the user with instructions for how to proceed. The information shown to the user, combined with data available to an engineer, should be enough to determine what went wrong. </li></ul><br /><br /><b><span>Test error handling </span></b><br /><br />The most common sections of code to remain untested is error handling code. Don&#8217;t skip test coverage here. Bad error handling code can cause unreproducible bugs and create great risk if it does not handle fatal errors well. <br /><br /><u>Guidelines for testing: </u><br /><br /><ul><li>Always test your error handling code. This is usually best accomplished by mocking or faking the component triggering the error. </li><li>It&#8217;s also a good practice to examine your log quality for all types of error handling.  </li></ul><br /><br /><b><span>Check for duplicate keys </span></b><br /><br />If unique identifiers or data access keys are generated using random data or are not guaranteed to be globally unique, duplicate keys may cause data corruption or concurrency issues. Key duplication bugs are very difficult to reproduce. <br /><br /><u>Guidelines for development: </u><br /><br /><ul><li>Try to guarantee uniqueness of all keys. </li><li>When not possible to guarantee unique keys, check if the recently generated key is already in use before using it. </li><li>Watch out for potential race conditions here and avoid them with synchronization. </li></ul><br /><br /><b><span>Test for concurrent data access </span></b><br /><br />Some bugs only reveal themselves when multiple clients are reading/writing the same data. Your stress tests might be covering cases like these, but if they are not, you should have special tests for concurrent data access. Case like these are often unreproducible. For example, a user may have two instances of your app running against the same account, and they may not realize this when reporting a bug. <br /><br /><u>Guidelines for testing: </u><br /><br /><ul><li>Always test for concurrent data access if it&#8217;s a feature of the system. Actually, even if it&#8217;s not a feature, verify that the system rejects it. Testing concurrency can be challenging. An approach that usually works for me is to create many worker threads that simultaneously attempt access and a master thread that monitors and verifies that some number of attempts were indeed concurrent, blocked or allowed as expected, and all were successful. Programmatic post-analysis of all attempts and changing system state may also be necessary to ensure that the system behaved well. </li></ul><br /><br /><b><span>Steer clear of undefined behavior and non-deterministic access to data </span></b><br /><br />Some APIs and basic operations have warnings about <a href="http://en.wikipedia.org/wiki/Undefined_behavior">undefined behavior</a> when in certain states or provided with certain input. Similarly, some data structures do not guarantee an iteration order (example: <a href="http://docs.oracle.com/javase/7/docs/api/java/util/Set.html#iterator()">Java&#8217;s Set</a>). Code that ignores these warnings may work fine most of the time but fail in unusual ways that are hard to reproduce.  <br /><br /><u>Guidelines for development: </u><br /><br /><ul><li>Understand when the APIs and operations you use might have undefined behavior and prevent those conditions. </li><li>Do not depend on data structure iteration order unless it is guaranteed. It is a common mistake to depend on the ordering of <a href="http://en.wikipedia.org/wiki/Set_(computer_science)">sets</a> or <a href="http://en.wikipedia.org/wiki/Associative_array">associative arrays</a>. </li></ul><br /><br /><b><span>Log the details for errors or test failures </span></b><br /><br />Issues described in this article can be easier to reproduce and debug when the logs contain enough detail to understand the conditions that led to an error. <br /><br /><u>Guidelines for development: </u><br /><br /><ul><li>Follow <a href="http://googletesting.blogspot.com/2013/06/optimal-logging.html">good logging practices</a>, especially in your error handling code. </li><li>If logs are stored on a user&#8217;s machine, create an easy way for them to provide you the logs. </li></ul><br /><u>Guidelines for testing: </u><br /><br /><ul><li>Save your test logs for potential analysis later. </li></ul><br /><br /><b><span>Anything to add? </span></b><br /><br />Have I missed any important guidelines for minimizing these bugs? What is your favorite hard-to-reproduce bug that you discovered and resolved? <br /><br />]]></description>
				<content:encoded><![CDATA[<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-W_7cqFXE2DA/Uu_ksr9HQOI/AAAAAAAAAFM/63eqQLF0cR8/s1600/cannot-repro.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-W_7cqFXE2DA/Uu_ksr9HQOI/AAAAAAAAAFM/63eqQLF0cR8/s1600/cannot-repro.png" height="307" width="320" /></a></div><br /><br /><i>by <a href="http://www.anthonysapps.com/anthony">Anthony Vallone</a></i><br /><br />Unreproducible bugs are the bane of my existence. Far too often, I find a bug, report it, and hear back that it’s not a bug because it can’t be reproduced. Of course, the bug is still there, waiting to prey on its next victim. These types of bugs can be very expensive due to increased investigation time and overall lifetime. They can also have a damaging effect on product perception when users reporting these bugs are effectively ignored. We should be doing more to prevent them. In this article, I’ll go over some obvious, and maybe not so obvious, development/testing guidelines that can reduce the likelihood of these bugs from occurring. <br /><br /><br /><b><span style="color: blue;">Avoid and test for race conditions, deadlocks, timing issues, memory corruption, uninitialized memory access, memory leaks, and resource issues </span></b><br /><br />I am lumping together many bug types in this section, but they are all related somewhat by how we test for them and how disproportionately hard they are to reproduce and debug. The root cause and effect can be separated by milliseconds or hours, and stack traces might be nonexistent or misleading. A system may fail in strange ways when exposed to unusual traffic spikes or insufficient resources. Race conditions and deadlocks may only be discovered during unique traffic patterns or resource configurations. Timing issues may only be noticed when many components are integrated and their performance parameters and failure/retry/timeout delays create a chaotic system. Memory corruption or uninitialized memory access may go unnoticed for a large percentage of calls but become fatal for rare states. Memory leaks may be negligible unless the system is exposed to load for an extended period of time. <br /><br /><u>Guidelines for development: </u><br /><br /><ul style="line-height: 1.5em; margin-bottom: 0px; margin-top: 0px; padding-bottom: 0px; padding-top: 0px;"><li>Simplify your synchronization logic. If it’s too hard to understand, it will be difficult to reproduce and debug complex concurrency problems. </li><li>Always obtain locks in the same order. This is a tried-and-true guideline to avoid deadlocks, but I still see code that breaks it periodically. Define an order for obtaining multiple locks and never change that order.  </li><li>Don’t optimize by creating many fine-grained locks, unless you have verified that they are needed. Extra locks increase concurrency complexity. </li><li>Avoid shared memory, unless you truly need it. Shared memory access is very easy to get wrong, and the bugs may be quite difficult to reproduce. </li></ul><br /><u>Guidelines for testing: </u><br /><br /><ul style="line-height: 1.5em; margin-bottom: 0px; margin-top: 0px; padding-bottom: 0px; padding-top: 0px;"><li><a href="http://en.wikipedia.org/wiki/Stress_testing">Stress test</a> your system regularly. You don't want to be surprised by unexpected failures when your system is under heavy load.  </li><li>Test timeouts. Create tests that mock/fake dependencies to test timeout code. If your timeout code does something bad, it may cause a bug that only occurs under certain system conditions. </li><li>Test with debug and optimized builds. You may find that a well behaved debug build works fine, but the system fails in strange ways once optimized. </li><li>Test under constrained resources. Try reducing the number of data centers, machines, processes, threads, available disk space, or available memory. Also try simulating reduced network bandwidth. </li><li>Test for longevity. Some bugs require a long period of time to reveal themselves. For example, persistent data may become corrupt over time. </li><li>Use dynamic analysis tools like <a href="http://en.wikipedia.org/wiki/Memory_debugger">memory debuggers</a>, <a href="https://code.google.com/p/address-sanitizer/">ASan</a>, <a href="https://code.google.com/p/thread-sanitizer/">TSan</a>, and <a href="https://code.google.com/p/memory-sanitizer/wiki/MemorySanitizer">MSan</a> regularly. They can help identify many categories of unreproducible memory/threading issues. </li></ul><br /><br /><b><span style="color: blue;">Enforce preconditions </span></b><br /><br />I’ve seen many well-meaning functions with a high tolerance for bad input. For example, consider this function: <br /><br /><pre style="background: #000000; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: white; overflow: auto; padding: 10px;"><span style="color: #76d6ff;">void</span> ScheduleEvent(<span style="color: #76d6ff;">int</span> timeDurationMilliseconds) {<br />  <span style="color: #76d6ff;">if</span> (timeDurationMilliseconds &lt;= 0) {<br />    timeDurationMilliseconds = 1;<br />  }<br />  ...<br />}<br /></pre><br />This function is trying to help the calling code by adjusting the input to an acceptable value, but it may be doing damage by masking a bug. The calling code may be experiencing any number of problems described in this article, and passing garbage to this function will always work fine. The more functions that are written with this level of tolerance, the harder it is to trace back to the root cause, and the more likely it becomes that the end user will see garbage. Enforcing preconditions, for instance by using asserts, may actually cause a higher number of failures for new systems, but as systems mature, and many minor/major problems are identified early on, these checks can help improve long-term reliability. <br /><br /><u>Guidelines for development: </u><br /><br /><ul style="line-height: 1.5em; margin-bottom: 0px; margin-top: 0px; padding-bottom: 0px; padding-top: 0px;"><li>Enforce preconditions in your functions unless you have a good reason not to. </li></ul><br /><br /><b><span style="color: blue;">Use defensive programming </span></b><br /><br /><a href="http://en.wikipedia.org/wiki/Defensive_programming">Defensive programming</a> is another tried-and-true technique that is great at minimizing unreproducible bugs. If your code calls a dependency to do something, and that dependency quietly fails or returns garbage, how does your code handle it? You could test for situations like this via mocking or faking, but it’s even better to have your production code do sanity checking on its dependencies. For example: <br /><br /><pre style="background: #000000; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: white; overflow: auto; padding: 10px;"><span style="color: #76d6ff;">double</span> GetMonthlyLoanPayment() {<br />  <span style="color: #76d6ff;">double</span> rate = GetTodaysInterestRateFromExternalSystem();<br />  <span style="color: #76d6ff;">if</span> (rate &lt; 0.001 || rate &gt; 0.5) {<br />    <span style="color: #76d6ff;">throw</span> BadInterestRate(rate);<br />  }<br />  ...<br />}<br /></pre><br /><u>Guidelines for development: </u><br /><br /><ul style="line-height: 1.5em; margin-bottom: 0px; margin-top: 0px; padding-bottom: 0px; padding-top: 0px;"><li>When possible, use defensive programming to verify the work of your dependencies with known risks of failure like user-provided data, I/O operations, and RPC calls. </li></ul><br /><u>Guidelines for testing: </u><br /><br /><ul style="line-height: 1.5em; margin-bottom: 0px; margin-top: 0px; padding-bottom: 0px; padding-top: 0px;"><li>Use <a href="http://en.wikipedia.org/wiki/Fuzz_testing">fuzz testing</a> to test your systems hardiness when enduring bad data. </li></ul><br /><br /><b><span style="color: blue;">Don’t hide all errors from the user </span></b><br /><br />There has been a trend in recent years toward hiding failures from users at all costs. In many cases, it makes perfect sense, but in some, we have gone overboard. Code that is very quiet and permissive during minor failures will allow an uninformed user to continue working in a failed state. The software may ultimately reach a fatal tipping point, and all the error conditions that led to failure have been ignored. If the user doesn’t know about the prior errors, they will not be able to report them, and you may not be able to reproduce them. <br /><br /><u>Guidelines for development: </u><br /><br /><ul style="line-height: 1.5em; margin-bottom: 0px; margin-top: 0px; padding-bottom: 0px; padding-top: 0px;"><li>Only hide errors from the user when you are certain that there is no impact to system state or the user. </li><li>Any error with impact to the user should be reported to the user with instructions for how to proceed. The information shown to the user, combined with data available to an engineer, should be enough to determine what went wrong. </li></ul><br /><br /><b><span style="color: blue;">Test error handling </span></b><br /><br />The most common sections of code to remain untested is error handling code. Don’t skip test coverage here. Bad error handling code can cause unreproducible bugs and create great risk if it does not handle fatal errors well. <br /><br /><u>Guidelines for testing: </u><br /><br /><ul style="line-height: 1.5em; margin-bottom: 0px; margin-top: 0px; padding-bottom: 0px; padding-top: 0px;"><li>Always test your error handling code. This is usually best accomplished by mocking or faking the component triggering the error. </li><li>It’s also a good practice to examine your log quality for all types of error handling.  </li></ul><br /><br /><b><span style="color: blue;">Check for duplicate keys </span></b><br /><br />If unique identifiers or data access keys are generated using random data or are not guaranteed to be globally unique, duplicate keys may cause data corruption or concurrency issues. Key duplication bugs are very difficult to reproduce. <br /><br /><u>Guidelines for development: </u><br /><br /><ul style="line-height: 1.5em; margin-bottom: 0px; margin-top: 0px; padding-bottom: 0px; padding-top: 0px;"><li>Try to guarantee uniqueness of all keys. </li><li>When not possible to guarantee unique keys, check if the recently generated key is already in use before using it. </li><li>Watch out for potential race conditions here and avoid them with synchronization. </li></ul><br /><br /><b><span style="color: blue;">Test for concurrent data access </span></b><br /><br />Some bugs only reveal themselves when multiple clients are reading/writing the same data. Your stress tests might be covering cases like these, but if they are not, you should have special tests for concurrent data access. Case like these are often unreproducible. For example, a user may have two instances of your app running against the same account, and they may not realize this when reporting a bug. <br /><br /><u>Guidelines for testing: </u><br /><br /><ul style="line-height: 1.5em; margin-bottom: 0px; margin-top: 0px; padding-bottom: 0px; padding-top: 0px;"><li>Always test for concurrent data access if it’s a feature of the system. Actually, even if it’s not a feature, verify that the system rejects it. Testing concurrency can be challenging. An approach that usually works for me is to create many worker threads that simultaneously attempt access and a master thread that monitors and verifies that some number of attempts were indeed concurrent, blocked or allowed as expected, and all were successful. Programmatic post-analysis of all attempts and changing system state may also be necessary to ensure that the system behaved well. </li></ul><br /><br /><b><span style="color: blue;">Steer clear of undefined behavior and non-deterministic access to data </span></b><br /><br />Some APIs and basic operations have warnings about <a href="http://en.wikipedia.org/wiki/Undefined_behavior">undefined behavior</a> when in certain states or provided with certain input. Similarly, some data structures do not guarantee an iteration order (example: <a href="http://docs.oracle.com/javase/7/docs/api/java/util/Set.html#iterator()">Java’s Set</a>). Code that ignores these warnings may work fine most of the time but fail in unusual ways that are hard to reproduce.  <br /><br /><u>Guidelines for development: </u><br /><br /><ul style="line-height: 1.5em; margin-bottom: 0px; margin-top: 0px; padding-bottom: 0px; padding-top: 0px;"><li>Understand when the APIs and operations you use might have undefined behavior and prevent those conditions. </li><li>Do not depend on data structure iteration order unless it is guaranteed. It is a common mistake to depend on the ordering of <a href="http://en.wikipedia.org/wiki/Set_(computer_science)">sets</a> or <a href="http://en.wikipedia.org/wiki/Associative_array">associative arrays</a>. </li></ul><br /><br /><b><span style="color: blue;">Log the details for errors or test failures </span></b><br /><br />Issues described in this article can be easier to reproduce and debug when the logs contain enough detail to understand the conditions that led to an error. <br /><br /><u>Guidelines for development: </u><br /><br /><ul style="line-height: 1.5em; margin-bottom: 0px; margin-top: 0px; padding-bottom: 0px; padding-top: 0px;"><li>Follow <a href="http://googletesting.blogspot.com/2013/06/optimal-logging.html">good logging practices</a>, especially in your error handling code. </li><li>If logs are stored on a user’s machine, create an easy way for them to provide you the logs. </li></ul><br /><u>Guidelines for testing: </u><br /><br /><ul style="line-height: 1.5em; margin-bottom: 0px; margin-top: 0px; padding-bottom: 0px; padding-top: 0px;"><li>Save your test logs for potential analysis later. </li></ul><br /><br /><b><span style="color: blue;">Anything to add? </span></b><br /><br />Have I missed any important guidelines for minimizing these bugs? What is your favorite hard-to-reproduce bug that you discovered and resolved? <br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/minimizing-unreproducible-bugs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>The Google Test and Development Environment &#8211; Pt. 3: Code, Build, and Test</title>
		<link>https://googledata.org/google-testing/the-google-test-and-development-environment-pt-3-code-build-and-test/</link>
		<comments>https://googledata.org/google-testing/the-google-test-and-development-environment-pt-3-code-build-and-test/#comments</comments>
		<pubDate>Tue, 21 Jan 2014 19:03:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=0906cff3f77c93b9c52488b4a2c3e944</guid>
		<description><![CDATA[<i>by <a href="http://www.anthonysapps.com/anthony">Anthony Vallone</a></i><br /><i><br /></i><i>This is the third in a series of articles about our work environment. See the <a href="http://googletesting.blogspot.com/2013/12/the-google-test-and-development.html">first</a>&#160;and <a href="http://googletesting.blogspot.com/2014/01/the-google-test-and-development.html">second</a>.</i><br /><br />I will never forget the awe I felt when running my first load test on my first project at Google. At previous companies I&#8217;ve worked, running a substantial load test took quite a bit of resource planning and preparation. At Google, I wrote less than 100 lines of code and was simulating tens of thousands of users after just minutes of prep work. The ease with which I was able to accomplish this is due to the impressive coding, building, and testing tools available at Google. In this article, I will discuss these tools and how they affect our test and development process. <br /><br /><b>Coding and building </b><br /><br />The tools and process for coding and building make it very easy to change production and test code. Even though we are a large company, we have managed to remain nimble. In a matter of minutes or hours, you can edit, test, review, and submit code to head. We have achieved this without sacrificing code quality by heavily investing in tools, testing, and infrastructure, and by prioritizing code reviews. <br /><br />Most production and test code is in a single, company-wide source control repository (open source projects like Chromium and Android have their own). There is a great deal of code sharing in the codebase, and this provides an incredible suite of code to build on. Most code is also in a single branch, so the majority of development is done at head. All code is also navigable, searchable, and editable from the browser. You&#8217;ll find code in numerous languages, but Java, C++, Python, Go, and JavaScript are the most common. <br /><br />Have a strong preference for editor? Engineers are free to choose from many IDEs and editors. The most common are Eclipse, Emacs, Vim, and IntelliJ, but many others are used as well. Engineers that are passionate about their prefered editors have built up and shared some truly impressive editor plugins/tooling over the years. <br /><br />Code reviews for all submissions are enforced via source control tooling. This also applies to test code, as our test code is held to the same standards as production code. The reviews are done via web-based code review tools that even include automatically generated test results. The process is very streamlined and efficient. Engineers can change and submit code in any part of the repository, but it must get reviewed by owners of the code being changed. This is great, because you can easily change code that your team depends on, rather than merely request a change to code you do not own. <br /><br />The <a href="http://google-engtools.blogspot.com/2011/08/build-in-cloud-how-build-system-works.html">Google build system</a> is used for building most code, and it is designed to work across many languages and platforms. It is remarkably simple to define and build targets. You won&#8217;t be needing that old Makefile book. <br /><br /><b>Running jobs and tests </b><br /><br />We have some pretty amazing machine and job management tools at Google. There is a generally available pool of machines in many data centers around the globe. The job management service makes it very easy to start jobs on arbitrary machines in any of these data centers. Failing machines are automatically removed from the pool, so tests rarely fail due to machine issues. With a little effort, you can also set up monitoring and pager alerting for your important jobs. <br /><br />From any machine you can spin up a massive number of tests and run them in parallel across many machines in the pool, via a single command. Each of these tests are run in a standard, isolated environment, so we rarely run into the &#8220;it works on my machine!&#8221; issue. <br /><br />Before code is submitted, <a href="http://googletesting.blogspot.com/2008/09/presubmit-and-performance.html">presubmit</a> tests can be run that will find all tests that depend transitively on the change and run them. You can also define presubmit rules that run checks on a code change and verify that tests were run before allowing submission. <br /><br />Once you&#8217;ve submitted test code, the build and test system automatically registers the test, and starts building/testing continuously. If the test starts failing, your team will get notification emails. You can also visit a test dashboard for your team and get details about test runs and test data. Monitoring the build/test status is made even easier with our build orbs designed and built by Googlers. These small devices will glow red if the build starts failing. Many teams have had fun customizing these orbs to various shapes, including a statue of liberty with a glowing torch. <br /><br /><div><a href="http://3.bp.blogspot.com/-il9jbjZdgxk/Ut7DeUdUIeI/AAAAAAAAAE8/J9FqDTO6DG0/s1600/liberty.png"><img border="0" src="http://3.bp.blogspot.com/-il9jbjZdgxk/Ut7DeUdUIeI/AAAAAAAAAE8/J9FqDTO6DG0/s1600/liberty.png" height="320" width="153"></a></div><div><i>Statue of LORBerty </i></div><br />Running larger integration and end-to-end tests takes a little more work, but we have some excellent tools to help with these tests as well: Integration test runners, hermetic environment creation, virtual machine service, web test frameworks, etc. <br /><br /><b>The impact </b><br /><br />So how do these tools actually affect our productivity? For starters, the code is easy to find, edit, review, and submit. Engineers are free to choose tools that make them most productive. Before and after submission, running small tests is trivial, and running large tests is relatively easy. Since tests are easy to create and run, it&#8217;s fairly simple to maintain a green build, which most teams do most of the time. This allows us to spend more time on real problems and less on the things that shouldn&#8217;t even be problems. It allows us to focus on creating rigorous tests. It dramatically accelerates the development process that can <a href="http://paulbuchheit.blogspot.com/2009/01/communicating-with-code.html">prototype Gmail in a day</a> and code/test/release service features on a daily schedule. And, of course, it lets us focus on the fun stuff. <br /><br /><b>Thoughts? </b><br /><br />We are interested to hear your thoughts on this topic. Google has the resources to build tools like this, but would small or medium size companies benefit from a similar investment in its infrastructure? Did Google create the infrastructure or did the infrastructure create Google? <br /><br />]]></description>
				<content:encoded><![CDATA[<i>by <a href="http://www.anthonysapps.com/anthony">Anthony Vallone</a></i><br /><i><br /></i><i>This is the third in a series of articles about our work environment. See the <a href="http://googletesting.blogspot.com/2013/12/the-google-test-and-development.html">first</a>&nbsp;and <a href="http://googletesting.blogspot.com/2014/01/the-google-test-and-development.html">second</a>.</i><br /><br />I will never forget the awe I felt when running my first load test on my first project at Google. At previous companies I’ve worked, running a substantial load test took quite a bit of resource planning and preparation. At Google, I wrote less than 100 lines of code and was simulating tens of thousands of users after just minutes of prep work. The ease with which I was able to accomplish this is due to the impressive coding, building, and testing tools available at Google. In this article, I will discuss these tools and how they affect our test and development process. <br /><br /><b>Coding and building </b><br /><br />The tools and process for coding and building make it very easy to change production and test code. Even though we are a large company, we have managed to remain nimble. In a matter of minutes or hours, you can edit, test, review, and submit code to head. We have achieved this without sacrificing code quality by heavily investing in tools, testing, and infrastructure, and by prioritizing code reviews. <br /><br />Most production and test code is in a single, company-wide source control repository (open source projects like Chromium and Android have their own). There is a great deal of code sharing in the codebase, and this provides an incredible suite of code to build on. Most code is also in a single branch, so the majority of development is done at head. All code is also navigable, searchable, and editable from the browser. You’ll find code in numerous languages, but Java, C++, Python, Go, and JavaScript are the most common. <br /><br />Have a strong preference for editor? Engineers are free to choose from many IDEs and editors. The most common are Eclipse, Emacs, Vim, and IntelliJ, but many others are used as well. Engineers that are passionate about their prefered editors have built up and shared some truly impressive editor plugins/tooling over the years. <br /><br />Code reviews for all submissions are enforced via source control tooling. This also applies to test code, as our test code is held to the same standards as production code. The reviews are done via web-based code review tools that even include automatically generated test results. The process is very streamlined and efficient. Engineers can change and submit code in any part of the repository, but it must get reviewed by owners of the code being changed. This is great, because you can easily change code that your team depends on, rather than merely request a change to code you do not own. <br /><br />The <a href="http://google-engtools.blogspot.com/2011/08/build-in-cloud-how-build-system-works.html">Google build system</a> is used for building most code, and it is designed to work across many languages and platforms. It is remarkably simple to define and build targets. You won’t be needing that old Makefile book. <br /><br /><b>Running jobs and tests </b><br /><br />We have some pretty amazing machine and job management tools at Google. There is a generally available pool of machines in many data centers around the globe. The job management service makes it very easy to start jobs on arbitrary machines in any of these data centers. Failing machines are automatically removed from the pool, so tests rarely fail due to machine issues. With a little effort, you can also set up monitoring and pager alerting for your important jobs. <br /><br />From any machine you can spin up a massive number of tests and run them in parallel across many machines in the pool, via a single command. Each of these tests are run in a standard, isolated environment, so we rarely run into the “it works on my machine!” issue. <br /><br />Before code is submitted, <a href="http://googletesting.blogspot.com/2008/09/presubmit-and-performance.html">presubmit</a> tests can be run that will find all tests that depend transitively on the change and run them. You can also define presubmit rules that run checks on a code change and verify that tests were run before allowing submission. <br /><br />Once you’ve submitted test code, the build and test system automatically registers the test, and starts building/testing continuously. If the test starts failing, your team will get notification emails. You can also visit a test dashboard for your team and get details about test runs and test data. Monitoring the build/test status is made even easier with our build orbs designed and built by Googlers. These small devices will glow red if the build starts failing. Many teams have had fun customizing these orbs to various shapes, including a statue of liberty with a glowing torch. <br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-il9jbjZdgxk/Ut7DeUdUIeI/AAAAAAAAAE8/J9FqDTO6DG0/s1600/liberty.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-il9jbjZdgxk/Ut7DeUdUIeI/AAAAAAAAAE8/J9FqDTO6DG0/s1600/liberty.png" height="320" width="153" /></a></div><div style="text-align: center;"><i>Statue of LORBerty </i></div><br />Running larger integration and end-to-end tests takes a little more work, but we have some excellent tools to help with these tests as well: Integration test runners, hermetic environment creation, virtual machine service, web test frameworks, etc. <br /><br /><b>The impact </b><br /><br />So how do these tools actually affect our productivity? For starters, the code is easy to find, edit, review, and submit. Engineers are free to choose tools that make them most productive. Before and after submission, running small tests is trivial, and running large tests is relatively easy. Since tests are easy to create and run, it’s fairly simple to maintain a green build, which most teams do most of the time. This allows us to spend more time on real problems and less on the things that shouldn’t even be problems. It allows us to focus on creating rigorous tests. It dramatically accelerates the development process that can <a href="http://paulbuchheit.blogspot.com/2009/01/communicating-with-code.html">prototype Gmail in a day</a> and code/test/release service features on a daily schedule. And, of course, it lets us focus on the fun stuff. <br /><br /><b>Thoughts? </b><br /><br />We are interested to hear your thoughts on this topic. Google has the resources to build tools like this, but would small or medium size companies benefit from a similar investment in its infrastructure? Did Google create the infrastructure or did the infrastructure create Google? <br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/the-google-test-and-development-environment-pt-3-code-build-and-test/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>The Google Test and Development Environment &#8211; Pt. 2: Dogfooding and Office Software</title>
		<link>https://googledata.org/google-testing/the-google-test-and-development-environment-pt-2-dogfooding-and-office-software/</link>
		<comments>https://googledata.org/google-testing/the-google-test-and-development-environment-pt-2-dogfooding-and-office-software/#comments</comments>
		<pubDate>Fri, 03 Jan 2014 18:41:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=d8c93f38838ac082e1528cff8738cefc</guid>
		<description><![CDATA[<i>by <a href="http://www.anthonysapps.com/anthony">Anthony Vallone</a></i><br /><i><br /></i><i>This is the second in a series of articles about our work environment. See the <a href="http://googletesting.blogspot.com/2013/12/the-google-test-and-development.html">first</a>. </i><br /><br />There are few things as frustrating as getting hampered in your work by a bug in a product you depend on. What if it&#8217;s a product developed by your company? Do you report/fix the issue or just work around it and hope it&#8217;ll go away soon? In this article, I&#8217;ll cover how and why Google <a href="http://en.wikipedia.org/wiki/Eating_your_own_dog_food">dogfoods</a> its own products. <br /><br /><b>Dogfooding </b><br /><br />Google makes heavy use of its own products. We have a large ecosystem of development/office tools and use them for nearly everything we do. Because we use them on a daily basis, we can dogfood releases company-wide before launching to the public. These dogfood versions often have features unavailable to the public but may be less stable. Instability is exactly what you want in your tools, right? Or, would you rather that frustration be passed on to your company&#8217;s customers? Of course not! <br /><br />Dogfooding is an important part of our test process. Test teams do their best to find problems before dogfooding, but we all know that testing is never perfect. We often get dogfood bug reports for edge and corner cases not initially covered by testing. We also get many comments about overall product quality and usability. This internal feedback has, on many occasions, changed product design. <br /><br />Not surprisingly, test-focused engineers often have a lot to say during the dogfood phase. I don&#8217;t think there is a single public-facing product that I have not reported bugs on. I really appreciate the fact that I can provide feedback on so many products before release. <br /><br />Interested in helping to test Google products? Many of our products have feedback links built-in. Some also have Beta releases available. For example, you can start using <a href="https://www.google.com/intl/en/chrome/browser/beta.html">Chrome Beta</a> and help us file bugs. <br /><br /><b>Office software </b><br /><br />From system design documents, to test plans, to discussions about beer brewing techniques, our products are used internally. A company&#8217;s choice of office tools can have a big impact on productivity, and it is fortunate for Google that we have such a comprehensive suite. The tools have a consistently simple UI (no manual required), perform very well, encourage collaboration, and auto-save in the cloud. Now that I am used to these tools, I would certainly have a hard time going back to the tools of previous companies I have worked. I&#8217;m sure I would forget to click the save buttons for years to come. <br /><br />Examples of frequently used tools by engineers: <br /><ul><li><a href="http://www.google.com/drive/apps.html">Google Drive Apps</a> (Docs, Sheets, Slides, etc.) are used for design documents, test plans, project data, data analysis, presentations, and more.</li><li><a href="https://mail.google.com/intl/en/mail/help/about.html">Gmail</a> and <a href="https://www.google.com/hangouts/">Hangouts</a> are used for email and chat.</li><li><a href="https://support.google.com/calendar">Google Calendar</a> is used to schedule all meetings, reserve conference rooms, and setup video conferencing using Hangouts.</li><li><a href="https://maps.google.com/">Google Maps</a> is used to map office floors.</li><li><a href="https://support.google.com/groups">Google Groups</a> are used for email lists.</li><li><a href="https://support.google.com/sites">Google Sites</a> are used to host team pages, engineering docs, and more.</li><li><a href="https://cloud.google.com/products/app-engine">Google App Engine</a> hosts many corporate, development, and test apps.</li><li><a href="https://www.google.com/intl/en/chrome/browser">Chrome</a> is our primary browser on all platforms.</li><li><a href="https://support.google.com/plus">Google+</a> is used for organizing internal communities on topics such as food or C++, and for socializing.</li></ul><br /><b>Thoughts? </b><br /><br />We are interested to hear your thoughts on this topic. Do you dogfood your company&#8217;s products? Do your office tools help or hinder your productivity? What office software and tools do you find invaluable for your job? Could you use Google Docs/Sheets for large test plans? <br /><br /><div><a href="http://googletesting.blogspot.com/2014/01/the-google-test-and-development_21.html">(Continue to part 3)</a></div>]]></description>
				<content:encoded><![CDATA[<i>by <a href="http://www.anthonysapps.com/anthony">Anthony Vallone</a></i><br /><i><br /></i><i>This is the second in a series of articles about our work environment. See the <a href="http://googletesting.blogspot.com/2013/12/the-google-test-and-development.html">first</a>. </i><br /><br />There are few things as frustrating as getting hampered in your work by a bug in a product you depend on. What if it’s a product developed by your company? Do you report/fix the issue or just work around it and hope it’ll go away soon? In this article, I’ll cover how and why Google <a href="http://en.wikipedia.org/wiki/Eating_your_own_dog_food">dogfoods</a> its own products. <br /><br /><b>Dogfooding </b><br /><br />Google makes heavy use of its own products. We have a large ecosystem of development/office tools and use them for nearly everything we do. Because we use them on a daily basis, we can dogfood releases company-wide before launching to the public. These dogfood versions often have features unavailable to the public but may be less stable. Instability is exactly what you want in your tools, right? Or, would you rather that frustration be passed on to your company’s customers? Of course not! <br /><br />Dogfooding is an important part of our test process. Test teams do their best to find problems before dogfooding, but we all know that testing is never perfect. We often get dogfood bug reports for edge and corner cases not initially covered by testing. We also get many comments about overall product quality and usability. This internal feedback has, on many occasions, changed product design. <br /><br />Not surprisingly, test-focused engineers often have a lot to say during the dogfood phase. I don’t think there is a single public-facing product that I have not reported bugs on. I really appreciate the fact that I can provide feedback on so many products before release. <br /><br />Interested in helping to test Google products? Many of our products have feedback links built-in. Some also have Beta releases available. For example, you can start using <a href="https://www.google.com/intl/en/chrome/browser/beta.html">Chrome Beta</a> and help us file bugs. <br /><br /><b>Office software </b><br /><br />From system design documents, to test plans, to discussions about beer brewing techniques, our products are used internally. A company’s choice of office tools can have a big impact on productivity, and it is fortunate for Google that we have such a comprehensive suite. The tools have a consistently simple UI (no manual required), perform very well, encourage collaboration, and auto-save in the cloud. Now that I am used to these tools, I would certainly have a hard time going back to the tools of previous companies I have worked. I’m sure I would forget to click the save buttons for years to come. <br /><br />Examples of frequently used tools by engineers: <br /><ul style="line-height: 1em; margin-bottom: 0px; margin-top: 0px; padding-bottom: 0px; padding-top: 0px;"><li><a href="http://www.google.com/drive/apps.html">Google Drive Apps</a> (Docs, Sheets, Slides, etc.) are used for design documents, test plans, project data, data analysis, presentations, and more.</li><li><a href="https://mail.google.com/intl/en/mail/help/about.html">Gmail</a> and <a href="https://www.google.com/hangouts/">Hangouts</a> are used for email and chat.</li><li><a href="https://support.google.com/calendar">Google Calendar</a> is used to schedule all meetings, reserve conference rooms, and setup video conferencing using Hangouts.</li><li><a href="https://maps.google.com/">Google Maps</a> is used to map office floors.</li><li><a href="https://support.google.com/groups">Google Groups</a> are used for email lists.</li><li><a href="https://support.google.com/sites">Google Sites</a> are used to host team pages, engineering docs, and more.</li><li><a href="https://cloud.google.com/products/app-engine">Google App Engine</a> hosts many corporate, development, and test apps.</li><li><a href="https://www.google.com/intl/en/chrome/browser">Chrome</a> is our primary browser on all platforms.</li><li><a href="https://support.google.com/plus">Google+</a> is used for organizing internal communities on topics such as food or C++, and for socializing.</li></ul><br /><b>Thoughts? </b><br /><br />We are interested to hear your thoughts on this topic. Do you dogfood your company’s products? Do your office tools help or hinder your productivity? What office software and tools do you find invaluable for your job? Could you use Google Docs/Sheets for large test plans? <br /><br /><div style="text-align: center;"><a href="http://googletesting.blogspot.com/2014/01/the-google-test-and-development_21.html">(Continue to part 3)</a></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/the-google-test-and-development-environment-pt-2-dogfooding-and-office-software/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>The Google Test and Development Environment &#8211; Pt. 1: Office and Equipment</title>
		<link>https://googledata.org/google-testing/the-google-test-and-development-environment-pt-1-office-and-equipment/</link>
		<comments>https://googledata.org/google-testing/the-google-test-and-development-environment-pt-1-office-and-equipment/#comments</comments>
		<pubDate>Fri, 20 Dec 2013 19:58:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=f348d63257320d45443e3e97c53db299</guid>
		<description><![CDATA[<i>by <a href="http://www.anthonysapps.com/anthony">Anthony Vallone</a></i><br /><br />When conducting interviews, I often get questions about our workspace and engineering environment. What IDEs do you use? What programming languages are most common? What kind of tools do you have for testing? What does the workspace look like? <br /><br />Google is a company that is constantly pushing to improve itself. Just like software development itself, most environment improvements happen via a bottom-up approach. All engineers are responsible for fine-tuning, experimenting with, and improving our process, with a goal of eliminating barriers to creating products that amaze.  <br /><br />Office space and engineering equipment can have a considerable impact on productivity. I&#8217;ll focus on these areas of our work environment in this first article of a series on the topic. <br /><br /><b>Office layout </b><br /><br />Google is a highly collaborative workplace, so the open floor plan suits our engineering process. Project teams composed of Software Engineers (SWEs), Software Engineers in Test (SETs), and Test Engineers (TEs) all sit near each other or in large rooms together. The test-focused engineers are involved in every step of the development process, so it&#8217;s critical for them to sit with the product developers. This keeps the lines of communication open.  <br /><br /><div><a href="http://1.bp.blogspot.com/-i9JDR9-1_0Y/UrSew1LuOTI/AAAAAAAAAEU/4d0DnlNkANM/s1600/google-munich.jpg"><img border="0" src="http://1.bp.blogspot.com/-i9JDR9-1_0Y/UrSew1LuOTI/AAAAAAAAAEU/4d0DnlNkANM/s400/google-munich.jpg" height="265" width="400"></a></div><div><i>Google Munich </i></div><br />The office space is far from rigid, and teams often rearrange desks to suit their preferences. The facilities team recently finished renovating a new floor in the New York City office, and after a day of engineering debates on optimal arrangements and white board diagrams, the floor was completely transformed. <br /><br />Besides the main office areas, there are lounge areas to which Googlers go for a change of scenery or a little peace and quiet. If you are trying to avoid becoming a casualty of The Great Foam Dart War, lounges are a great place to hide. <br /><br /><div><a href="http://4.bp.blogspot.com/-PU5Uno6oYWY/UrSe4rg-QtI/AAAAAAAAAEc/KNmnkb6Tt3c/s1600/dublin.jpg"><img border="0" src="http://4.bp.blogspot.com/-PU5Uno6oYWY/UrSe4rg-QtI/AAAAAAAAAEc/KNmnkb6Tt3c/s400/dublin.jpg" height="265" width="400"></a></div><div><i>Google Dublin </i></div><br /><b>Working with remote teams </b><br /><br />Google&#8217;s worldwide headquarters is in Mountain View, CA, but it&#8217;s a very global company, and our project teams are often distributed across multiple sites. To help keep teams well connected, most of our conference rooms have video conferencing equipment. We make frequent use of this equipment for team meetings, presentations, and quick chats. <br /><br /><div><a href="http://4.bp.blogspot.com/-Mtimvx4gLl8/UrSfDPmirCI/AAAAAAAAAEk/YqW83CQpC5o/s1600/boston.jpg"><img border="0" src="http://4.bp.blogspot.com/-Mtimvx4gLl8/UrSfDPmirCI/AAAAAAAAAEk/YqW83CQpC5o/s400/boston.jpg" height="298" width="400"></a></div><div><i>Google Boston </i></div><br /><b>What&#8217;s at your desk? </b><br /><br />All engineers get high-end machines and have easy access to data center machines for running large tasks. A new member on my team recently mentioned that his Google machine has 16 times the memory of the machine at his previous company. <br /><br />Most Google code runs on Linux, so the majority of development is done on Linux workstations. However, those that work on client code for Windows, OS X, or mobile, develop on relevant OSes. For displays, each engineer has a choice of either two 24 inch monitors or one 30 inch monitor. We also get our choice of laptop, picking from various models of Chromebook, MacBook, or Linux. These come in handy when going to meetings, lounges, or working remotely.  <br /><br /><div><a href="http://2.bp.blogspot.com/-f5ukeR3cgzI/UrSfH83SnJI/AAAAAAAAAEs/6SwfI6Ijfxo/s1600/zurich.jpg"><img border="0" src="http://2.bp.blogspot.com/-f5ukeR3cgzI/UrSfH83SnJI/AAAAAAAAAEs/6SwfI6Ijfxo/s400/zurich.jpg" height="266" width="400"></a></div><div><i>Google Zurich </i></div><br /><b>Thoughts? </b><br /><br />We are interested to hear your thoughts on this topic. Do you prefer an open-office layout, cubicles, or private offices? Should test teams be embedded with development teams, or should they operate separately? Do the benefits of offering engineers high-end equipment outweigh the costs? <br /><br /><div><a href="http://googletesting.blogspot.com/2014/01/the-google-test-and-development.html">(Continue to part 2)</a></div><div><br /></div>]]></description>
				<content:encoded><![CDATA[<i>by <a href="http://www.anthonysapps.com/anthony">Anthony Vallone</a></i><br /><br />When conducting interviews, I often get questions about our workspace and engineering environment. What IDEs do you use? What programming languages are most common? What kind of tools do you have for testing? What does the workspace look like? <br /><br />Google is a company that is constantly pushing to improve itself. Just like software development itself, most environment improvements happen via a bottom-up approach. All engineers are responsible for fine-tuning, experimenting with, and improving our process, with a goal of eliminating barriers to creating products that amaze.  <br /><br />Office space and engineering equipment can have a considerable impact on productivity. I’ll focus on these areas of our work environment in this first article of a series on the topic. <br /><br /><b>Office layout </b><br /><br />Google is a highly collaborative workplace, so the open floor plan suits our engineering process. Project teams composed of Software Engineers (SWEs), Software Engineers in Test (SETs), and Test Engineers (TEs) all sit near each other or in large rooms together. The test-focused engineers are involved in every step of the development process, so it’s critical for them to sit with the product developers. This keeps the lines of communication open.  <br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-i9JDR9-1_0Y/UrSew1LuOTI/AAAAAAAAAEU/4d0DnlNkANM/s1600/google-munich.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-i9JDR9-1_0Y/UrSew1LuOTI/AAAAAAAAAEU/4d0DnlNkANM/s400/google-munich.jpg" height="265" width="400" /></a></div><div style="text-align: center;"><i>Google Munich </i></div><br />The office space is far from rigid, and teams often rearrange desks to suit their preferences. The facilities team recently finished renovating a new floor in the New York City office, and after a day of engineering debates on optimal arrangements and white board diagrams, the floor was completely transformed. <br /><br />Besides the main office areas, there are lounge areas to which Googlers go for a change of scenery or a little peace and quiet. If you are trying to avoid becoming a casualty of The Great Foam Dart War, lounges are a great place to hide. <br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-PU5Uno6oYWY/UrSe4rg-QtI/AAAAAAAAAEc/KNmnkb6Tt3c/s1600/dublin.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-PU5Uno6oYWY/UrSe4rg-QtI/AAAAAAAAAEc/KNmnkb6Tt3c/s400/dublin.jpg" height="265" width="400" /></a></div><div style="text-align: center;"><i>Google Dublin </i></div><br /><b>Working with remote teams </b><br /><br />Google’s worldwide headquarters is in Mountain View, CA, but it’s a very global company, and our project teams are often distributed across multiple sites. To help keep teams well connected, most of our conference rooms have video conferencing equipment. We make frequent use of this equipment for team meetings, presentations, and quick chats. <br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-Mtimvx4gLl8/UrSfDPmirCI/AAAAAAAAAEk/YqW83CQpC5o/s1600/boston.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-Mtimvx4gLl8/UrSfDPmirCI/AAAAAAAAAEk/YqW83CQpC5o/s400/boston.jpg" height="298" width="400" /></a></div><div style="text-align: center;"><i>Google Boston </i></div><br /><b>What’s at your desk? </b><br /><br />All engineers get high-end machines and have easy access to data center machines for running large tasks. A new member on my team recently mentioned that his Google machine has 16 times the memory of the machine at his previous company. <br /><br />Most Google code runs on Linux, so the majority of development is done on Linux workstations. However, those that work on client code for Windows, OS X, or mobile, develop on relevant OSes. For displays, each engineer has a choice of either two 24 inch monitors or one 30 inch monitor. We also get our choice of laptop, picking from various models of Chromebook, MacBook, or Linux. These come in handy when going to meetings, lounges, or working remotely.  <br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-f5ukeR3cgzI/UrSfH83SnJI/AAAAAAAAAEs/6SwfI6Ijfxo/s1600/zurich.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-f5ukeR3cgzI/UrSfH83SnJI/AAAAAAAAAEs/6SwfI6Ijfxo/s400/zurich.jpg" height="266" width="400" /></a></div><div style="text-align: center;"><i>Google Zurich </i></div><br /><b>Thoughts? </b><br /><br />We are interested to hear your thoughts on this topic. Do you prefer an open-office layout, cubicles, or private offices? Should test teams be embedded with development teams, or should they operate separately? Do the benefits of offering engineers high-end equipment outweigh the costs? <br /><br /><div style="text-align: center;"><a href="http://googletesting.blogspot.com/2014/01/the-google-test-and-development.html">(Continue to part 2)</a></div><div style="text-align: center;"><br /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/the-google-test-and-development-environment-pt-1-office-and-equipment/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>WebRTC Audio Quality Testing</title>
		<link>https://googledata.org/google-testing/webrtc-audio-quality-testing/</link>
		<comments>https://googledata.org/google-testing/webrtc-audio-quality-testing/#comments</comments>
		<pubDate>Fri, 08 Nov 2013 18:47:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=c870033d250d027502bcc2b0b5bde1c8</guid>
		<description><![CDATA[<i>by Patrik H&#246;glund </i><br /><br />The <a href="http://www.webrtc.org/">WebRTC project</a> is all about enabling peer-to-peer video, voice and data transfer in the browser. To give our users the best possible experience we need to adapt the quality of the media to the bandwidth and processing power we have available. Our users encounter a wide variety of network conditions and run on a variety of devices, from powerful desktop machines with a wired broadband connection to laptops on WiFi to mobile phones on spotty 3G networks. <br /><br />We want to ensure good quality for all these use cases in our implementation in Chrome. To some extent we can do this with manual testing, but the breakneck pace of Chrome development makes it very hard to keep up (several hundred patches land every day)! Therefore, we'd like to test the quality of our video and voice transfer with an automated test. Ideally, we&#8217;d like to test for the most common network scenarios our users encounter, but to start we chose to implement a test where we have plenty of CPU and bandwidth. This article covers how we built such a test. <br /><br /><span><b>Quality Metrics </b></span><br />First, we must define what we want to measure. For instance, the <a href="https://code.google.com/p/chromium/codesearch#chromium/src/chrome/browser/media/chrome_webrtc_video_quality_browsertest.cc&#38;q=chrome_webrtc_vi&#38;sq=package:chromium">WebRTC video quality test</a> uses <a href="http://en.wikipedia.org/wiki/Peak_signal-to-noise_ratio">peak signal-to-noise ratio</a> and <a href="http://en.wikipedia.org/wiki/Structural_similarity">structural similarity</a> to measure the quality of the video (or to be more precise, how much the output video differs from the input video; see <a href="http://www.youtube.com/watch?v=IbLNm3LsMaw&#38;list=SPSIUOFhnxEiCODb8XQB-RUQ0RGNZ2yW7d">this GTAC 13 talk</a> for more details). The quality of the user experience is a subjective thing though. Arguably, one probably needs dozens of different metrics to really ensure a good user experience. For video, we would have to (at the very least) have some measure for frame rate and resolution besides correctness. To have the system send somewhat correct video frames seemed the most important though, which is why we chose the above metrics. <br /><br />For this test we wanted to start with a similar correctness metric, but for audio. It turns out there's an algorithm called <a href="http://en.wikipedia.org/wiki/PESQ">Perceptual Evaluation of Speech Quality</a> (PESQ) which analyzes two audio files and tell you how similar they are, while taking into account how the human ear works (so it ignores differences a normal person would not hear anyway). That's great, since we want our metrics to measure the user experience as much as possible.  There are many aspects of voice transfer you could measure, such as latency (which is really important for voice calls), but for now we'll focus on measuring how much a voice audio stream gets distorted by the transfer. <br /><br /><span><b>Feeding Audio Into WebRTC </b></span><br />In the WebRTC case we already <a href="https://code.google.com/p/chromium/codesearch#chromium/src/chrome/browser/media/chrome_webrtc_browsertest.cc&#38;sq=package:chromium">had a test</a> which would launch a Chrome browser, open two tabs, get the tabs talking to each other through a signaling server and set up a call on a single machine. Then we just needed to figure out how to feed a reference audio file into a WebRTC call and record what comes out on the other end. This part was actually harder than it sounds. The main WebRTC use case is that the web page acquires the user's mic through <a href="http://dev.w3.org/2011/webrtc/editor/getusermedia.html">getUserMedia</a>, sets up a PeerConnection with some remote peer and sends the audio from the mic through the connection to the peer where it is played in the peer's audio output device.  <br /><br /><div><a href="http://4.bp.blogspot.com/-vYo0ghEwlHk/Un0uYrQ13WI/AAAAAAAAAD4/NBy_CaccBYk/s1600/img1.png"><img border="0" height="316" src="http://4.bp.blogspot.com/-vYo0ghEwlHk/Un0uYrQ13WI/AAAAAAAAAD4/NBy_CaccBYk/s640/img1.png" width="640"></a></div><br /><br /><div><i>WebRTC calls transmit voice, video and data peer-to-peer, over the Internet. </i></div><br />But since this is an automated test, of course we could not have someone speak in a microphone every time the test runs; we had to feed in a known input file, so we had something to compare the recorded output audio against.  <br /><br />Could we duct-tape a small stereo to the mic and play our audio file on the stereo? That's not very maintainable or reliable, not to mention annoying for anyone in the vicinity. What about some kind of fake device driver which makes a microphone-like device appear on the device level? The problem with that is that it's hard to control a driver from the userspace test program. Also, the test will be more complex and flaky, and the driver interaction will not be portable.<a href="http://googletesting.blogspot.com/#foot1"><sup>[1]</sup></a><br /><br />Instead, we chose to sidestep this problem. We used a solution where we load an audio file with <a href="https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html">WebAudio</a> and play that straight into the peer connection through the <a href="https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/webrtc-integration.html">WebAudio-PeerConnection integration</a>. That way we start the playing of the file from the same renderer process as the call itself, which made it a lot easier to time the start and end of the file. We still needed to be careful to avoid playing the file too early or too late, so we don't clip the audio at the start or end - that would destroy our PESQ scores! - but it turned out to be a workable approach.<a href="http://googletesting.blogspot.com/#foot2"><sup>[2]</sup></a><br /><br /><span><b>Recording the Output </b></span><br />Alright, so now we could get a WebRTC call set up with a known audio file with decent control of when the file starts playing. Now we had to record the output. There are a number of possible solutions. The most end-to-end way is to straight up record what the system sends to default audio out (like speakers or headphones). Alternatively, we could write a hook in our application to dump our audio as late as possible, like when we're just about to send it to the sound card. <br /><br />We went with the former. Our colleagues in the Chrome video stack team in Kirkland had already found  that it's possible to configure a Windows or Linux machine to send the system's audio output (i.e. what plays on the speakers) to a virtual recording device. If we make that virtual recording device the default one, simply invoking SoundRecorder.exe and arecord respectively will record what the system is playing out.  <br /><br />They found this works well if one also uses the <a href="http://sox.sourceforge.net/">sox</a> utility to eliminate silence around the actual audio content (recall we had some safety margins at both ends to ensure we record the whole input file as playing through the WebRTC call). We adopted the same approach, since it records what the user would hear, and yet uses only standard tools. This means we don't have to install additional software on the myriad machines that will run this test.<a href="http://googletesting.blogspot.com/#foot3"><sup>[3]</sup></a><br /><br /><span><b>Analyzing Audio </b></span><br />The only remaining step was to compare the silence-eliminated recording with the input file. When we first did this, we got a really bad score (like 2.0 out of 5.0, which means PESQ thinks it&#8217;s barely legible). This didn't seem to make sense, since both the input and recording sounded very similar. Turns out we didn&#8217;t think about the following: <br /><br /><ul><li>We were comparing a full-band (24 kHz) input file to a wide-band (8 kHz) result (although both files were sampled at 48 kHz). This essentially amounted to a low pass filtering of the result file. </li><li>Both files were in stereo, but PESQ is only mono-aware. </li><li>The files were 32-bit, but the PESQ implementation is designed for 16 bits. </li></ul><br />As you can see, it&#8217;s important to pay attention to what format arecord and SoundRecorder.exe records in, and make sure the input file is recorded in the same way. After correcting the input file and &#8220;rebasing&#8221;, we got the score up to about 4.0.<a href="http://googletesting.blogspot.com/#foot4"><sup>[4]</sup></a><br /><br />Thus, we ended up with an automated test that runs continously on the torrent of Chrome change lists and protects WebRTC's ability to transmit sound. You can see the <a href="https://code.google.com/p/chromium/codesearch#chromium/src/chrome/browser/media/chrome_webrtc_audio_quality_browsertest.cc&#38;q=chrome_webrtc_a&#38;sq=package:chromium">finished code here</a>. With automated tests and cleverly chosen metrics you can protect against most regressions a user would notice. If your product includes video and audio handling, such a test is a great addition to your testing mix.  <br /><br /><div><a href="http://3.bp.blogspot.com/-pYtwelNAxwE/Un0vxiP2SdI/AAAAAAAAAEE/7Ta3KOYspd0/s1600/img2.png"><img border="0" src="http://3.bp.blogspot.com/-pYtwelNAxwE/Un0vxiP2SdI/AAAAAAAAAEE/7Ta3KOYspd0/s1600/img2.png"></a></div><br /><div><i>How the components of the test fit together. </i></div><br /><span><b>Future work </b></span><br /><br /><ul><li>It might be possible to write a Chrome extension which dumps the audio from Chrome to a file. That way we get a simpler-to-maintain and portable solution. It would be less end-to-end but more than worth it due to the simplified maintenance and setup. Also, the recording tools we use are not perfect and add some distortion, which makes the score less accurate. </li><li>There are other algorithms than PESQ to consider - for instance, <a href="http://en.wikipedia.org/wiki/POLQA">POLQA</a> is the successor to PESQ and is better at analyzing high-bandwidth audio signals. </li><li>We are working on a solution which will run this test under simulated network conditions. Simulated networks combined with this test is a really powerful way to test our behavior under various packet loss and delay scenarios and ensure we deliver a good experience to all our users, not just those with great broadband connections. Stay tuned for future articles on that topic! </li><li>Investigate feasibility of running this set-up on mobile devices. </li></ul><br /><br /><hr /><br /><sup>1</sup>It would be tolerable if the driver was just looping the input file, eliminating the need for the test to control the driver (i.e. the test doesn't have to tell the driver to start playing the file). This is actually what we do in the video quality test. It's a much better fit to take this approach on the video side since each recorded video frame is independent of the others. We can easily embed barcodes into each frame and evaluate them independently.  <br /><br />This seems much harder for audio. We could possibly do <a href="http://en.wikipedia.org/wiki/Audio_watermark">audio watermarking</a>, or we could embed a kind of start marker (for instance, using DTMF tones) in the first two seconds of the input file and play the real content after that, and then do some fancy audio processing on the receiving end to figure out the start and end of the input audio. We chose not to pursue this approach due to its complexity. <br /><br /><sup>2</sup>Unfortunately, this also means we will not test the capturer path (which handles microphones, etc in WebRTC). This is an example of the frequent tradeoffs one has to do when designing an end-to-end test. Often we have to trade end-to-endness (how close the test is to the user experience) with robustness and simplicity of a test. It's not worth it to cover 5% more of the code if the test become unreliable or radically more expensive to maintain. Another example: A WebRTC call will generally involve two peers on different devices separated by the real-world internet. Writing such a test and making it reliable would be extremely difficult, so we make the test single-machine and hope we catch most of the bugs anyway. <br /><br /><sup>3</sup>It's important to keep the continuous build setup simple and the build machines easy to configure - otherwise you will inevitably pay a heavy price in maintenance when you try to scale your testing up. <br /><br /><sup>4</sup>When sending audio over the internet, we have to compress it since lossless audio consumes way too much bandwidth. WebRTC audio generally sounds great, but there's still compression artifacts if you listen closely (and, in fact, the recording tools are not perfect and add some distorsion as well). Given that this test is more about detecting regressions than measuring some absolute notion of quality, we'd like to downplay those artifacts. As our Kirkland colleagues found, one of the ways to do that is to "rebase" the input file. That means we start with a pristine recording, feed that through the WebRTC call and record what comes out on the other end. After manually verifying the quality, we use that as our input file for the actual test. In our case, it pushed our PESQ score up from 3 to about 4 (out of 5), which gives us a bit more sensitivity to regressions. <br /><br />]]></description>
				<content:encoded><![CDATA[<i>by Patrik Höglund </i><br /><br />The <a href="http://www.webrtc.org/">WebRTC project</a> is all about enabling peer-to-peer video, voice and data transfer in the browser. To give our users the best possible experience we need to adapt the quality of the media to the bandwidth and processing power we have available. Our users encounter a wide variety of network conditions and run on a variety of devices, from powerful desktop machines with a wired broadband connection to laptops on WiFi to mobile phones on spotty 3G networks. <br /><br />We want to ensure good quality for all these use cases in our implementation in Chrome. To some extent we can do this with manual testing, but the breakneck pace of Chrome development makes it very hard to keep up (several hundred patches land every day)! Therefore, we'd like to test the quality of our video and voice transfer with an automated test. Ideally, we’d like to test for the most common network scenarios our users encounter, but to start we chose to implement a test where we have plenty of CPU and bandwidth. This article covers how we built such a test. <br /><br /><span style="font-size: large;"><b>Quality Metrics </b></span><br />First, we must define what we want to measure. For instance, the <a href="https://code.google.com/p/chromium/codesearch#chromium/src/chrome/browser/media/chrome_webrtc_video_quality_browsertest.cc&amp;q=chrome_webrtc_vi&amp;sq=package:chromium">WebRTC video quality test</a> uses <a href="http://en.wikipedia.org/wiki/Peak_signal-to-noise_ratio">peak signal-to-noise ratio</a> and <a href="http://en.wikipedia.org/wiki/Structural_similarity">structural similarity</a> to measure the quality of the video (or to be more precise, how much the output video differs from the input video; see <a href="http://www.youtube.com/watch?v=IbLNm3LsMaw&amp;list=SPSIUOFhnxEiCODb8XQB-RUQ0RGNZ2yW7d">this GTAC 13 talk</a> for more details). The quality of the user experience is a subjective thing though. Arguably, one probably needs dozens of different metrics to really ensure a good user experience. For video, we would have to (at the very least) have some measure for frame rate and resolution besides correctness. To have the system send somewhat correct video frames seemed the most important though, which is why we chose the above metrics. <br /><br />For this test we wanted to start with a similar correctness metric, but for audio. It turns out there's an algorithm called <a href="http://en.wikipedia.org/wiki/PESQ">Perceptual Evaluation of Speech Quality</a> (PESQ) which analyzes two audio files and tell you how similar they are, while taking into account how the human ear works (so it ignores differences a normal person would not hear anyway). That's great, since we want our metrics to measure the user experience as much as possible.  There are many aspects of voice transfer you could measure, such as latency (which is really important for voice calls), but for now we'll focus on measuring how much a voice audio stream gets distorted by the transfer. <br /><br /><span style="font-size: large;"><b>Feeding Audio Into WebRTC </b></span><br />In the WebRTC case we already <a href="https://code.google.com/p/chromium/codesearch#chromium/src/chrome/browser/media/chrome_webrtc_browsertest.cc&amp;sq=package:chromium">had a test</a> which would launch a Chrome browser, open two tabs, get the tabs talking to each other through a signaling server and set up a call on a single machine. Then we just needed to figure out how to feed a reference audio file into a WebRTC call and record what comes out on the other end. This part was actually harder than it sounds. The main WebRTC use case is that the web page acquires the user's mic through <a href="http://dev.w3.org/2011/webrtc/editor/getusermedia.html">getUserMedia</a>, sets up a PeerConnection with some remote peer and sends the audio from the mic through the connection to the peer where it is played in the peer's audio output device.  <br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-vYo0ghEwlHk/Un0uYrQ13WI/AAAAAAAAAD4/NBy_CaccBYk/s1600/img1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="316" src="http://4.bp.blogspot.com/-vYo0ghEwlHk/Un0uYrQ13WI/AAAAAAAAAD4/NBy_CaccBYk/s640/img1.png" width="640" /></a></div><br /><br /><div style="text-align: center;"><i>WebRTC calls transmit voice, video and data peer-to-peer, over the Internet. </i></div><br />But since this is an automated test, of course we could not have someone speak in a microphone every time the test runs; we had to feed in a known input file, so we had something to compare the recorded output audio against.  <br /><br />Could we duct-tape a small stereo to the mic and play our audio file on the stereo? That's not very maintainable or reliable, not to mention annoying for anyone in the vicinity. What about some kind of fake device driver which makes a microphone-like device appear on the device level? The problem with that is that it's hard to control a driver from the userspace test program. Also, the test will be more complex and flaky, and the driver interaction will not be portable.<a href="http://googletesting.blogspot.com/2013/11/webrtc-audio-quality-testing.html#foot1"><sup>[1]</sup></a><br /><br />Instead, we chose to sidestep this problem. We used a solution where we load an audio file with <a href="https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html">WebAudio</a> and play that straight into the peer connection through the <a href="https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/webrtc-integration.html">WebAudio-PeerConnection integration</a>. That way we start the playing of the file from the same renderer process as the call itself, which made it a lot easier to time the start and end of the file. We still needed to be careful to avoid playing the file too early or too late, so we don't clip the audio at the start or end - that would destroy our PESQ scores! - but it turned out to be a workable approach.<a href="http://googletesting.blogspot.com/2013/11/webrtc-audio-quality-testing.html#foot2"><sup>[2]</sup></a><br /><br /><span style="font-size: large;"><b>Recording the Output </b></span><br />Alright, so now we could get a WebRTC call set up with a known audio file with decent control of when the file starts playing. Now we had to record the output. There are a number of possible solutions. The most end-to-end way is to straight up record what the system sends to default audio out (like speakers or headphones). Alternatively, we could write a hook in our application to dump our audio as late as possible, like when we're just about to send it to the sound card. <br /><br />We went with the former. Our colleagues in the Chrome video stack team in Kirkland had already found  that it's possible to configure a Windows or Linux machine to send the system's audio output (i.e. what plays on the speakers) to a virtual recording device. If we make that virtual recording device the default one, simply invoking SoundRecorder.exe and arecord respectively will record what the system is playing out.  <br /><br />They found this works well if one also uses the <a href="http://sox.sourceforge.net/">sox</a> utility to eliminate silence around the actual audio content (recall we had some safety margins at both ends to ensure we record the whole input file as playing through the WebRTC call). We adopted the same approach, since it records what the user would hear, and yet uses only standard tools. This means we don't have to install additional software on the myriad machines that will run this test.<a href="http://googletesting.blogspot.com/2013/11/webrtc-audio-quality-testing.html#foot3"><sup>[3]</sup></a><br /><br /><span style="font-size: large;"><b>Analyzing Audio </b></span><br />The only remaining step was to compare the silence-eliminated recording with the input file. When we first did this, we got a really bad score (like 2.0 out of 5.0, which means PESQ thinks it’s barely legible). This didn't seem to make sense, since both the input and recording sounded very similar. Turns out we didn’t think about the following: <br /><br /><ul style="line-height: 1em; margin-bottom: 0px; margin-top: 0px; padding-bottom: 0px; padding-top: 0px;"><li>We were comparing a full-band (24 kHz) input file to a wide-band (8 kHz) result (although both files were sampled at 48 kHz). This essentially amounted to a low pass filtering of the result file. </li><li>Both files were in stereo, but PESQ is only mono-aware. </li><li>The files were 32-bit, but the PESQ implementation is designed for 16 bits. </li></ul><br />As you can see, it’s important to pay attention to what format arecord and SoundRecorder.exe records in, and make sure the input file is recorded in the same way. After correcting the input file and “rebasing”, we got the score up to about 4.0.<a href="http://googletesting.blogspot.com/2013/11/webrtc-audio-quality-testing.html#foot4"><sup>[4]</sup></a><br /><br />Thus, we ended up with an automated test that runs continously on the torrent of Chrome change lists and protects WebRTC's ability to transmit sound. You can see the <a href="https://code.google.com/p/chromium/codesearch#chromium/src/chrome/browser/media/chrome_webrtc_audio_quality_browsertest.cc&amp;q=chrome_webrtc_a&amp;sq=package:chromium">finished code here</a>. With automated tests and cleverly chosen metrics you can protect against most regressions a user would notice. If your product includes video and audio handling, such a test is a great addition to your testing mix.  <br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-pYtwelNAxwE/Un0vxiP2SdI/AAAAAAAAAEE/7Ta3KOYspd0/s1600/img2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-pYtwelNAxwE/Un0vxiP2SdI/AAAAAAAAAEE/7Ta3KOYspd0/s1600/img2.png" /></a></div><br /><div style="text-align: center;"><i>How the components of the test fit together. </i></div><br /><span style="font-size: large;"><b>Future work </b></span><br /><br /><ul style="line-height: 1em; margin-bottom: 0px; margin-top: 0px; padding-bottom: 0px; padding-top: 0px;"><li>It might be possible to write a Chrome extension which dumps the audio from Chrome to a file. That way we get a simpler-to-maintain and portable solution. It would be less end-to-end but more than worth it due to the simplified maintenance and setup. Also, the recording tools we use are not perfect and add some distortion, which makes the score less accurate. </li><li>There are other algorithms than PESQ to consider - for instance, <a href="http://en.wikipedia.org/wiki/POLQA">POLQA</a> is the successor to PESQ and is better at analyzing high-bandwidth audio signals. </li><li>We are working on a solution which will run this test under simulated network conditions. Simulated networks combined with this test is a really powerful way to test our behavior under various packet loss and delay scenarios and ensure we deliver a good experience to all our users, not just those with great broadband connections. Stay tuned for future articles on that topic! </li><li>Investigate feasibility of running this set-up on mobile devices. </li></ul><br /><br /><hr /><br /><sup id="foot1">1</sup>It would be tolerable if the driver was just looping the input file, eliminating the need for the test to control the driver (i.e. the test doesn't have to tell the driver to start playing the file). This is actually what we do in the video quality test. It's a much better fit to take this approach on the video side since each recorded video frame is independent of the others. We can easily embed barcodes into each frame and evaluate them independently.  <br /><br />This seems much harder for audio. We could possibly do <a href="http://en.wikipedia.org/wiki/Audio_watermark">audio watermarking</a>, or we could embed a kind of start marker (for instance, using DTMF tones) in the first two seconds of the input file and play the real content after that, and then do some fancy audio processing on the receiving end to figure out the start and end of the input audio. We chose not to pursue this approach due to its complexity. <br /><br /><sup id="foot2">2</sup>Unfortunately, this also means we will not test the capturer path (which handles microphones, etc in WebRTC). This is an example of the frequent tradeoffs one has to do when designing an end-to-end test. Often we have to trade end-to-endness (how close the test is to the user experience) with robustness and simplicity of a test. It's not worth it to cover 5% more of the code if the test become unreliable or radically more expensive to maintain. Another example: A WebRTC call will generally involve two peers on different devices separated by the real-world internet. Writing such a test and making it reliable would be extremely difficult, so we make the test single-machine and hope we catch most of the bugs anyway. <br /><br /><sup id="foot3">3</sup>It's important to keep the continuous build setup simple and the build machines easy to configure - otherwise you will inevitably pay a heavy price in maintenance when you try to scale your testing up. <br /><br /><sup id="foot4">4</sup>When sending audio over the internet, we have to compress it since lossless audio consumes way too much bandwidth. WebRTC audio generally sounds great, but there's still compression artifacts if you listen closely (and, in fact, the recording tools are not perfect and add some distorsion as well). Given that this test is more about detecting regressions than measuring some absolute notion of quality, we'd like to downplay those artifacts. As our Kirkland colleagues found, one of the ways to do that is to "rebase" the input file. That means we start with a pristine recording, feed that through the WebRTC call and record what comes out on the other end. After manually verifying the quality, we use that as our input file for the actual test. In our case, it pushed our PESQ score up from 3 to about 4 (out of 5), which gives us a bit more sensitivity to regressions. <br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/webrtc-audio-quality-testing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Espresso for Android is here!</title>
		<link>https://googledata.org/google-testing/espresso-for-android-is-here/</link>
		<comments>https://googledata.org/google-testing/espresso-for-android-is-here/#comments</comments>
		<pubDate>Fri, 18 Oct 2013 21:26:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>
		<category><![CDATA[android]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=dd78de03a255f68c0200bd23fdb348df</guid>
		<description><![CDATA[Cross-posted from the Android Developers Google+ PageEarlier this year, we presented Espresso at GTAC as a solution to the UI testing problem. Today we are announcing the launch of the developer preview for Espresso!The compelling thing about developin...]]></description>
				<content:encoded><![CDATA[<i>Cross-posted from the <a href="https://plus.sandbox.google.com/+AndroidDevelopers/posts">Android Developers Google+ Page</a></i><br /><br />Earlier this year, we presented Espresso at GTAC as a solution to the UI testing problem. Today we are announcing the launch of the developer preview for Espresso!<br /><br />The compelling thing about developing Espresso was making it easy and fun for developers to write reliable UI tests. Espresso has a small, predictable, and easy to learn API, which is still open for customization. But most importantly - Espresso removes the need to think about the complexity of multi-threaded testing. With Espresso, you can think procedurally and write concise, beautiful, and reliable Android UI tests quickly.<br /><br />Espresso is now being used by over 30 applications within Google (Drive, Maps and G+, just to name a few). Starting from today, Espresso will also be available to our great developer community. We hope you will also enjoy testing your applications with Espresso and looking forward to your feedback and contributions!<br /><br /><div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-KD6xUPTsNjs/UmGmdurLO5I/AAAAAAAAADo/mjf_ZPao27c/s1600/logo.jpeg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-KD6xUPTsNjs/UmGmdurLO5I/AAAAAAAAADo/mjf_ZPao27c/s1600/logo.jpeg" /></a></div><br /><div style="text-align: center;">Android Test Kit: <a href="https://code.google.com/p/android-test-kit/">https://code.google.com/p/android-test-kit/</a></div><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/espresso-for-android-is-here/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>How the Google+ Team Tests Mobile Apps</title>
		<link>https://googledata.org/google-testing/how-the-google-team-tests-mobile-apps/</link>
		<comments>https://googledata.org/google-testing/how-the-google-team-tests-mobile-apps/#comments</comments>
		<pubDate>Fri, 30 Aug 2013 19:30:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>
		<category><![CDATA[mobile]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=5e246733be683e3be8ffbfcaa87f9fe1</guid>
		<description><![CDATA[<i>by Eduardo Bravo Ortiz </i><br /><br />&#8220;Mobile first&#8221; is the motto these days for many companies. However, being able to test a mobile app in a meaningful way is very challenging. On the Google+ team we have had our share of trial and error that has led us to successful strategies for testing mobile applications on both iOS and Android. <br /><br /><span><b>General </b></span><br /><br /><ul><li>Understand the platform. Testing on Android is not the same as testing on iOS. The testing tools and frameworks available for each platform are significantly different. (e.g., Android uses Java while iOS uses Objective-C, UI layouts are built differently on each platform, UI testing frameworks also work very differently in both platforms.) </li><li>Stabilize your test suite and test environments. Flaky tests are worse than having no tests, because a flaky test pollutes your build health and decreases the credibility of your suite. </li><li>Break down testing into manageable pieces. There are too many complex pieces when testing on mobile (e.g., emulator/device state, actions triggered by the OS).  </li><li>Provide a <a href="http://googletesting.blogspot.com/2012/10/hermetic-servers.html">hermetic test</a> environment for your tests. Mobile UI tests are flaky by nature; don&#8217;t add more flakiness to them by having external dependencies. </li><li>Unit tests are the backbone of your mobile test strategy. Try to separate the app code logic from the UI as much as possible. This separation will make unit tests more granular and faster. </li></ul><br /><br /><b><span>Android Testing </span></b><br /><br /><b>Unit Tests </b><br />Separating UI code from code logic is especially hard in Android. For example, an Activity is expected to act as a controller and view at the same time; make sure you keep this in mind when writing unit tests. Another useful recommendation is to decouple unit tests from the Android emulator, this will remove the need to build an APK and install it and your tests will run much faster. <a href="http://pivotal.github.io/robolectric/">Robolectric</a> is a perfect tool for this; it stubs the implementation of the Android platform while running tests. <br /><br /><b>Hermetic UI Tests </b><br />A hermetic UI test typically runs as a test without network calls or external dependencies. Once the tests can run in a <a href="http://googletesting.blogspot.com/2012/10/hermetic-servers.html">hermetic environment</a>, a white box testing framework like <a href="http://www.youtube.com/watch?v=T7ugmCuNxDU">Espresso</a> can simulate user actions on the UI and is tightly coupled to the app code. Espresso will also synchronize your tests actions with events on the UI thread, reducing flakiness. More information on Espresso is coming in a future Google Testing Blog article. <br /><br /><div><b>Diagram: Non-Hermetic Flow vs. Hermetic Flow </b></div><div><a href="http://1.bp.blogspot.com/--yeG5Bgqzas/UiDv4W5iyWI/AAAAAAAAADQ/hwPYIYmaz9M/s1600/diagram1.png"><img border="0" height="199" src="http://1.bp.blogspot.com/--yeG5Bgqzas/UiDv4W5iyWI/AAAAAAAAADQ/hwPYIYmaz9M/s640/diagram1.png" width="640"></a></div><br /><br /><b>Monkey Tests </b><br />Monkey tests look for crashes and <a href="http://developer.android.com/training/articles/perf-anr.html">ANRs</a> by stressing your Android application. They exercise <a href="http://en.wikipedia.org/wiki/Pseudorandom_number_generator">pseudo-random</a> events like clicks or gestures on the app under test. Monkey test results are reproducible to a certain extent; timing and latency are not completely under your control and can cause a test failure. Re-running the same monkey test against the same configuration will often reproduce these failures, though. If you run them daily against different SDKs, they are very effective at catching bugs earlier in the development cycle of a new release. <br /><br /><b><span>iOS Testing </span></b><br /><br /><b>Unit Tests </b><br />Unit test frameworks like <a href="http://www.sente.ch/software/ocunit/">OCUnit</a>, which comes bundled with Xcode, or <a href="https://code.google.com/p/google-toolbox-for-mac/">GTMSenTestcase</a> are both good choices. <br /><br /><b>Hermetic UI Tests </b><br /><a href="https://github.com/kif-framework/KIF">KIF</a> has proven to be a powerful solution for writing Objective-C UI tests. It runs in-process which allows tests to be more tightly coupled with the app under test, making the tests inherently more stable. KIF allows iOS developers to write tests using the same language as their application. <br /><br />Following the same paradigm as Android UI tests, you want Objective-C tests to be hermetic. A good approach is to mock the server with pre-canned responses. Since KIF tests run in-process, responses can be built programmatically, making tests easier to maintain and more stable. <br /><br /><b>Monkey Tests </b><br />iOS has no equivalent native tool for writing monkey tests as Android does, however this type of test still adds value in iOS (e.g. we found 16 crashes in one of our recent Google+ releases). The Google+ team developed their own custom monkey testing framework, but there are also many third-party options available. <br /><br /><b><span>Backend Testing </span></b><br /><br />A mobile testing strategy is not complete without testing the integration between server backends and mobile clients. This is especially true when the release cycles of the mobile clients and backends are very different. A replay test strategy can be very effective at preventing backends from breaking mobile clients. The theory behind this strategy is to simulate mobile clients by having a set of golden request and response files that are known to be correct. The replay test suite should then send golden requests to the backend server and assert that the response returned by the server matches the expected golden response. Since client/server responses are often not completely deterministic, you will need to utilize a diffing tool that can ignore expected differences. <br /><br />To make this strategy successful you need a way to seed a repeatable data set on the backend and make all dependencies that are not relevant to your backend hermetic. Using in-memory servers with fake data or an RPC replay to external dependencies are good ways of achieving repeatable data sets and hermetic environments. Google+ mobile backend uses <a href="https://code.google.com/p/google-guice/">Guice</a> for dependency injection, which allows us to easily swap out dependencies with fake implementations during testing and seed data fixtures. <br /><br /><div><b>Diagram: Normal flow vs Replay Tests flow </b></div><div><a href="http://3.bp.blogspot.com/-3w15bC7RSj8/UiDwRP-Ob_I/AAAAAAAAADY/9gmTy3HDMZg/s1600/diagram2.png"><img border="0" height="230" src="http://3.bp.blogspot.com/-3w15bC7RSj8/UiDwRP-Ob_I/AAAAAAAAADY/9gmTy3HDMZg/s640/diagram2.png" width="640"></a></div><br /><br /><b><span>Conclusion </span></b><br /><br />Mobile app testing can be very challenging, but building a comprehensive test strategy that understands the nature of different platforms and tools is the key to success. Providing a reliable and hermetic test environment is as important as the tests you write. <br /><br />Finally, make sure you prioritize your automation efforts according to your team needs. This is how we prioritize on the Google+ team: <br /><ol><li>Unit tests: These should be your first priority in either Android or iOS. They run fast and are less flaky than any other type of tests. </li><li>Backend tests: Make sure your backend doesn&#8217;t break your mobile clients. Breakages are very likely to happen when the release cycle of mobile clients and backends are different. </li><li>UI tests: These are slower by nature and flaky. They also take more time to write and maintain. Make sure you provide coverage for at least the critical paths of your app. </li><li>Monkey tests: This is the final step to complete your mobile automation strategy. </li></ol><br /><br />Happy mobile testing from the Google+ team.]]></description>
				<content:encoded><![CDATA[<i>by Eduardo Bravo Ortiz </i><br /><br />“Mobile first” is the motto these days for many companies. However, being able to test a mobile app in a meaningful way is very challenging. On the Google+ team we have had our share of trial and error that has led us to successful strategies for testing mobile applications on both iOS and Android. <br /><br /><span style="color: blue;"><b>General </b></span><br /><br /><ul style="line-height: 1em; margin-bottom: 0px; margin-top: 0px; padding-bottom: 0px; padding-top: 0px;"><li>Understand the platform. Testing on Android is not the same as testing on iOS. The testing tools and frameworks available for each platform are significantly different. (e.g., Android uses Java while iOS uses Objective-C, UI layouts are built differently on each platform, UI testing frameworks also work very differently in both platforms.) </li><li>Stabilize your test suite and test environments. Flaky tests are worse than having no tests, because a flaky test pollutes your build health and decreases the credibility of your suite. </li><li>Break down testing into manageable pieces. There are too many complex pieces when testing on mobile (e.g., emulator/device state, actions triggered by the OS).  </li><li>Provide a <a href="http://googletesting.blogspot.com/2012/10/hermetic-servers.html">hermetic test</a> environment for your tests. Mobile UI tests are flaky by nature; don’t add more flakiness to them by having external dependencies. </li><li>Unit tests are the backbone of your mobile test strategy. Try to separate the app code logic from the UI as much as possible. This separation will make unit tests more granular and faster. </li></ul><br /><br /><b><span style="color: blue;">Android Testing </span></b><br /><br /><b>Unit Tests </b><br />Separating UI code from code logic is especially hard in Android. For example, an Activity is expected to act as a controller and view at the same time; make sure you keep this in mind when writing unit tests. Another useful recommendation is to decouple unit tests from the Android emulator, this will remove the need to build an APK and install it and your tests will run much faster. <a href="http://pivotal.github.io/robolectric/">Robolectric</a> is a perfect tool for this; it stubs the implementation of the Android platform while running tests. <br /><br /><b>Hermetic UI Tests </b><br />A hermetic UI test typically runs as a test without network calls or external dependencies. Once the tests can run in a <a href="http://googletesting.blogspot.com/2012/10/hermetic-servers.html">hermetic environment</a>, a white box testing framework like <a href="http://www.youtube.com/watch?v=T7ugmCuNxDU">Espresso</a> can simulate user actions on the UI and is tightly coupled to the app code. Espresso will also synchronize your tests actions with events on the UI thread, reducing flakiness. More information on Espresso is coming in a future Google Testing Blog article. <br /><br /><div style="text-align: center;"><b>Diagram: Non-Hermetic Flow vs. Hermetic Flow </b></div><div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/--yeG5Bgqzas/UiDv4W5iyWI/AAAAAAAAADQ/hwPYIYmaz9M/s1600/diagram1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="199" src="http://1.bp.blogspot.com/--yeG5Bgqzas/UiDv4W5iyWI/AAAAAAAAADQ/hwPYIYmaz9M/s640/diagram1.png" width="640" /></a></div><br /><br /><b>Monkey Tests </b><br />Monkey tests look for crashes and <a href="http://developer.android.com/training/articles/perf-anr.html">ANRs</a> by stressing your Android application. They exercise <a href="http://en.wikipedia.org/wiki/Pseudorandom_number_generator">pseudo-random</a> events like clicks or gestures on the app under test. Monkey test results are reproducible to a certain extent; timing and latency are not completely under your control and can cause a test failure. Re-running the same monkey test against the same configuration will often reproduce these failures, though. If you run them daily against different SDKs, they are very effective at catching bugs earlier in the development cycle of a new release. <br /><br /><b><span style="color: blue;">iOS Testing </span></b><br /><br /><b>Unit Tests </b><br />Unit test frameworks like <a href="http://www.sente.ch/software/ocunit/">OCUnit</a>, which comes bundled with Xcode, or <a href="https://code.google.com/p/google-toolbox-for-mac/">GTMSenTestcase</a> are both good choices. <br /><br /><b>Hermetic UI Tests </b><br /><a href="https://github.com/kif-framework/KIF">KIF</a> has proven to be a powerful solution for writing Objective-C UI tests. It runs in-process which allows tests to be more tightly coupled with the app under test, making the tests inherently more stable. KIF allows iOS developers to write tests using the same language as their application. <br /><br />Following the same paradigm as Android UI tests, you want Objective-C tests to be hermetic. A good approach is to mock the server with pre-canned responses. Since KIF tests run in-process, responses can be built programmatically, making tests easier to maintain and more stable. <br /><br /><b>Monkey Tests </b><br />iOS has no equivalent native tool for writing monkey tests as Android does, however this type of test still adds value in iOS (e.g. we found 16 crashes in one of our recent Google+ releases). The Google+ team developed their own custom monkey testing framework, but there are also many third-party options available. <br /><br /><b><span style="color: blue;">Backend Testing </span></b><br /><br />A mobile testing strategy is not complete without testing the integration between server backends and mobile clients. This is especially true when the release cycles of the mobile clients and backends are very different. A replay test strategy can be very effective at preventing backends from breaking mobile clients. The theory behind this strategy is to simulate mobile clients by having a set of golden request and response files that are known to be correct. The replay test suite should then send golden requests to the backend server and assert that the response returned by the server matches the expected golden response. Since client/server responses are often not completely deterministic, you will need to utilize a diffing tool that can ignore expected differences. <br /><br />To make this strategy successful you need a way to seed a repeatable data set on the backend and make all dependencies that are not relevant to your backend hermetic. Using in-memory servers with fake data or an RPC replay to external dependencies are good ways of achieving repeatable data sets and hermetic environments. Google+ mobile backend uses <a href="https://code.google.com/p/google-guice/">Guice</a> for dependency injection, which allows us to easily swap out dependencies with fake implementations during testing and seed data fixtures. <br /><br /><div style="text-align: center;"><b>Diagram: Normal flow vs Replay Tests flow </b></div><div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-3w15bC7RSj8/UiDwRP-Ob_I/AAAAAAAAADY/9gmTy3HDMZg/s1600/diagram2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="230" src="http://3.bp.blogspot.com/-3w15bC7RSj8/UiDwRP-Ob_I/AAAAAAAAADY/9gmTy3HDMZg/s640/diagram2.png" width="640" /></a></div><br /><br /><b><span style="color: blue;">Conclusion </span></b><br /><br />Mobile app testing can be very challenging, but building a comprehensive test strategy that understands the nature of different platforms and tools is the key to success. Providing a reliable and hermetic test environment is as important as the tests you write. <br /><br />Finally, make sure you prioritize your automation efforts according to your team needs. This is how we prioritize on the Google+ team: <br /><ol style="line-height: 1em; margin-bottom: 0px; margin-top: 0px; padding-bottom: 0px; padding-top: 0px;"><li>Unit tests: These should be your first priority in either Android or iOS. They run fast and are less flaky than any other type of tests. </li><li>Backend tests: Make sure your backend doesn’t break your mobile clients. Breakages are very likely to happen when the release cycle of mobile clients and backends are different. </li><li>UI tests: These are slower by nature and flaky. They also take more time to write and maintain. Make sure you provide coverage for at least the critical paths of your app. </li><li>Monkey tests: This is the final step to complete your mobile automation strategy. </li></ol><br /><br />Happy mobile testing from the Google+ team.]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/how-the-google-team-tests-mobile-apps/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Testing on the Toilet: Know Your Test Doubles</title>
		<link>https://googledata.org/google-testing/testing-on-the-toilet-know-your-test-doubles/</link>
		<comments>https://googledata.org/google-testing/testing-on-the-toilet-know-your-test-doubles/#comments</comments>
		<pubDate>Thu, 18 Jul 2013 17:45:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=f8e8c80bdcc8721d1ed82d91ddf9ae69</guid>
		<description><![CDATA[By Andrew Trenk <br /><br /><i>This article was adapted from a <a href="http://googletesting.blogspot.com/2007/01/introducing-testing-on-toilet.html">Google Testing on the Toilet</a> (TotT) episode. You can download a <a href="https://docs.google.com/file/d/0B_EQS8-2f7m5Y1lTcDRnekk3Rjg/edit?usp=sharing">printer-friendly version</a> of this TotT episode and post it in your office. </i><br /><br /><b>A test double is an object that can stand in for a real object in a test</b>, similar to how a stunt double stands in for an actor in a movie. These are sometimes all commonly referred to as &#8220;mocks&#8221;, but it's important to distinguish between the different types of test doubles since they all have different uses. <b>The most common types of test doubles are stubs, mocks, and fakes. </b><br /><br />A <b>stub</b> has no logic, and only returns what you tell it to return. <b>Stubs can be used when you need an object to return specific values in order to get your code under test into a certain state.</b> While it's usually easy to write stubs by hand, using a mocking framework is often a convenient way to reduce boilerplate. <br /><br /><pre><span>// Pass in a stub that was created by a mocking framework.</span><br />AccessManager <b>accessManager</b> = <span>new</span> AccessManager(<b>stubAuthenticationService</b>);<br /><span>// The user shouldn't have access when the authentication service returns false.</span><br />when(<b>stubAuthenticationService</b>.isAuthenticated(USER_ID)).thenReturn(<span>false</span>);<br />assertFalse(<b>accessManager</b>.userHasAccess(USER_ID));<br /><span>// The user should have access when the authentication service returns true. </span><br />when(<b>stubAuthenticationService</b>.isAuthenticated(USER_ID)).thenReturn(<span>true</span>);<br />assertTrue(<b>accessManager</b>.userHasAccess(USER_ID));<br /></pre><br />A <b>mock</b> has expectations about the way it should be called, and a test should fail if it&#8217;s not called that way. <b>Mocks are used to test interactions between objects</b>, and are useful in cases where there are no other visible state  changes or return results that you can verify (e.g. if your code reads from disk and you want to ensure that it doesn't do more than one disk read, you can use a mock to verify that the method that does the read is only called once). <br /><br /><pre><span>// Pass in a mock that was created by a mocking framework.</span><br />AccessManager <b>accessManager</b> = <span>new</span> AccessManager(<b>mockAuthenticationService</b>);<br /><b>accessManager</b>.userHasAccess(USER_ID);<br /><span>// The test should fail if accessManager.userHasAccess(USER_ID) didn't call</span><br /><span>// mockAuthenticationService.isAuthenticated(USER_ID) or if it called it more than once.</span><br />verify(<b>mockAuthenticationService</b>).isAuthenticated(USER_ID);</pre><br />A <b>fake</b> doesn&#8217;t use a mocking framework: it&#8217;s a lightweight implementation of an API that behaves like the real implementation, but isn't suitable for production (e.g. an in-memory database). <b>Fakes can be used when you can't use a real implementation in your test</b> (e.g. if the real implementation is too slow or it talks over the network). You shouldn't need to write your own fakes often since fakes should usually be created and maintained by the person or team that owns the real implementation. <br /><br /><pre><span>// Creating the fake is fast and easy.</span><br />AuthenticationService <b>fakeAuthenticationService</b> = <span>new</span> FakeAuthenticationService();<br />AccessManager <b>accessManager</b> = <span>new</span> AccessManager(<b>fakeAuthenticationService</b>);<br /><span>// The user shouldn't have access since the authentication service doesn't</span><br /><span>// know about the user.</span><br />assertFalse(<b>accessManager</b>.userHasAccess(USER_ID));<br /><span>// The user should have access after it's added to the authentication service.</span><br /><b>fakeAuthenticationService</b>.addAuthenticatedUser(USER_ID);<br />assertTrue(<b>accessManager</b>.userHasAccess(USER_ID));</pre><br /><i>The term &#8220;test double&#8221; was coined by Gerard Meszaros in the book xUnit Test Patterns. You can find more information about test doubles in the book, or on the book&#8217;s <a href="http://xunitpatterns.com/Test%20Double%20Patterns.html">website</a>. You can also find a discussion about the different types of test doubles in this <a href="http://martinfowler.com/articles/mocksArentStubs.html">article</a> by Martin Fowler. </i><br /><br />]]></description>
				<content:encoded><![CDATA[By Andrew Trenk <br /><br /><i>This article was adapted from a <a href="http://googletesting.blogspot.com/2007/01/introducing-testing-on-toilet.html">Google Testing on the Toilet</a> (TotT) episode. You can download a <a href="https://docs.google.com/file/d/0B_EQS8-2f7m5Y1lTcDRnekk3Rjg/edit?usp=sharing">printer-friendly version</a> of this TotT episode and post it in your office. </i><br /><br /><b>A test double is an object that can stand in for a real object in a test</b>, similar to how a stunt double stands in for an actor in a movie. These are sometimes all commonly referred to as “mocks”, but it's important to distinguish between the different types of test doubles since they all have different uses. <b>The most common types of test doubles are stubs, mocks, and fakes. </b><br /><br />A <b>stub</b> has no logic, and only returns what you tell it to return. <b>Stubs can be used when you need an object to return specific values in order to get your code under test into a certain state.</b> While it's usually easy to write stubs by hand, using a mocking framework is often a convenient way to reduce boilerplate. <br /><br /><pre style="background: #f9f9f9; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;"><span style="color: #4f8f00;">// Pass in a stub that was created by a mocking framework.</span><br />AccessManager <b>accessManager</b> = <span style="color: #0433ff;">new</span> AccessManager(<b>stubAuthenticationService</b>);<br /><span style="color: #4f8f00;">// The user shouldn't have access when the authentication service returns false.</span><br />when(<b>stubAuthenticationService</b>.isAuthenticated(USER_ID)).thenReturn(<span style="color: #0433ff;">false</span>);<br />assertFalse(<b>accessManager</b>.userHasAccess(USER_ID));<br /><span style="color: #4f8f00;">// The user should have access when the authentication service returns true. </span><br />when(<b>stubAuthenticationService</b>.isAuthenticated(USER_ID)).thenReturn(<span style="color: #0433ff;">true</span>);<br />assertTrue(<b>accessManager</b>.userHasAccess(USER_ID));<br /></pre><br />A <b>mock</b> has expectations about the way it should be called, and a test should fail if it’s not called that way. <b>Mocks are used to test interactions between objects</b>, and are useful in cases where there are no other visible state  changes or return results that you can verify (e.g. if your code reads from disk and you want to ensure that it doesn't do more than one disk read, you can use a mock to verify that the method that does the read is only called once). <br /><br /><pre style="background: #f9f9f9; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;"><span style="color: #4f8f00;">// Pass in a mock that was created by a mocking framework.</span><br />AccessManager <b>accessManager</b> = <span style="color: #0433ff;">new</span> AccessManager(<b>mockAuthenticationService</b>);<br /><b>accessManager</b>.userHasAccess(USER_ID);<br /><span style="color: #4f8f00;">// The test should fail if accessManager.userHasAccess(USER_ID) didn't call</span><br /><span style="color: #4f8f00;">// mockAuthenticationService.isAuthenticated(USER_ID) or if it called it more than once.</span><br />verify(<b>mockAuthenticationService</b>).isAuthenticated(USER_ID);</pre><br />A <b>fake</b> doesn’t use a mocking framework: it’s a lightweight implementation of an API that behaves like the real implementation, but isn't suitable for production (e.g. an in-memory database). <b>Fakes can be used when you can't use a real implementation in your test</b> (e.g. if the real implementation is too slow or it talks over the network). You shouldn't need to write your own fakes often since fakes should usually be created and maintained by the person or team that owns the real implementation. <br /><br /><pre style="background: #f9f9f9; border-color: #7b7b7b; border-style: solid; border-width: 1px; color: black; overflow: auto; padding: 10px;"><span style="color: #4f8f00;">// Creating the fake is fast and easy.</span><br />AuthenticationService <b>fakeAuthenticationService</b> = <span style="color: #0433ff;">new</span> FakeAuthenticationService();<br />AccessManager <b>accessManager</b> = <span style="color: #0433ff;">new</span> AccessManager(<b>fakeAuthenticationService</b>);<br /><span style="color: #4f8f00;">// The user shouldn't have access since the authentication service doesn't</span><br /><span style="color: #4f8f00;">// know about the user.</span><br />assertFalse(<b>accessManager</b>.userHasAccess(USER_ID));<br /><span style="color: #4f8f00;">// The user should have access after it's added to the authentication service.</span><br /><b>fakeAuthenticationService</b>.addAuthenticatedUser(USER_ID);<br />assertTrue(<b>accessManager</b>.userHasAccess(USER_ID));</pre><br /><i>The term “test double” was coined by Gerard Meszaros in the book xUnit Test Patterns. You can find more information about test doubles in the book, or on the book’s <a href="http://xunitpatterns.com/Test%20Double%20Patterns.html">website</a>. You can also find a discussion about the different types of test doubles in this <a href="http://martinfowler.com/articles/mocksArentStubs.html">article</a> by Martin Fowler. </i><br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/testing-on-the-toilet-know-your-test-doubles/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Optimal Logging</title>
		<link>https://googledata.org/google-testing/optimal-logging/</link>
		<comments>https://googledata.org/google-testing/optimal-logging/#comments</comments>
		<pubDate>Fri, 14 Jun 2013 14:58:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=99045ac8b2a79a62d8db2088c822d3fc</guid>
		<description><![CDATA[<i>by <a href="http://www.anthonysapps.com/anthony">Anthony Vallone</a></i><br /><br />How long does it take to find the root cause of a failure in your system? Five minutes? Five days? If you answered close to five minutes, it&#8217;s very likely that your production system and tests have great logging. All too often, seemingly unessential features like logging, exception handling, and (dare I say it) testing are an implementation afterthought. Like exception handling and testing, you really need to have a strategy for logging in both your systems and your tests. Never underestimate the power of logging. With optimal logging, you can even eliminate the necessity for debuggers. Below are some guidelines that have been useful to me over the years.<br /><br /><br /><b>Channeling Goldilocks</b><br /><br />Never log too much. Massive, disk-quota burning logs are a clear indicator that little thought was put in to logging. If you log too much, you&#8217;ll need to devise complex approaches to minimize disk access, maintain log history, archive large quantities of data, and query these large sets of data. More importantly, you&#8217;ll make it very difficult to find valuable information in all the chatter.<br /><br />The only thing worse than logging too much is logging too little. There are normally two main goals of logging: help with bug investigation and event confirmation. If your log can&#8217;t explain the cause of a bug or whether a certain transaction took place, you are logging too little.<br /><br />Good things to log: <br /><ul><li>Important startup configuration</li><li>Errors</li><li>Warnings</li><li>Changes to persistent data</li><li>Requests and responses between major system components</li><li>Significant state changes</li><li>User interactions</li><li>Calls with a known risk of failure</li><li>Waits on conditions that could take measurable time to satisfy</li><li>Periodic progress during long-running tasks</li><li>Significant branch points of logic and conditions that led to the branch</li><li>Summaries of processing steps or events from high level functions - Avoid logging every step of a complex process in low-level functions.</li></ul><br />Bad things to log: <br /><ul><li>Function entry - Don&#8217;t log a function entry unless it is significant or logged at the debug level.</li><li>Data within a loop - Avoid logging from many iterations of a loop. It is OK to log from iterations of small loops or to log periodically from large loops.</li><li>Content of large messages or files - Truncate or summarize the data in some way that will be useful to debugging.</li><li>Benign errors - Errors that are not really errors can confuse the log reader. This sometimes happens when exception handling is part of successful execution flow.</li><li>Repetitive errors - Do not repetitively log the same or similar error. This can quickly fill a log and hide the actual cause. Frequency of error types is best handled by monitoring. Logs only need to capture detail for some of those errors.</li></ul><br /><br /><b>There is More Than One Level</b><br /><br />Don't log everything at the same log level. Most logging libraries offer several log levels, and you can enable certain levels at system startup. This provides a convenient control for log verbosity.<br /><br />The classic levels are: <br /><ul><li>Debug - verbose and only useful while developing and/or debugging.</li><li>Info - the most popular level.</li><li>Warning - strange or unexpected states that are acceptable.</li><li>Error - something went wrong, but the process can recover.</li><li>Critical - the process cannot recover, and it will shutdown or restart.</li></ul><br />Practically speaking, only two log configurations are needed: <br /><ul><li>Production - Every level is enabled except debug. If something goes wrong in production, the logs should reveal the cause.</li><li>Development &#38; Debug - While developing new code or trying to reproduce a production issue, enable all levels.</li></ul><br /><br /><b>Test Logs Are Important Too</b><br /><br />Log quality is equally important in test and production code. When a test fails, the log should clearly show whether the failure was a problem with the test or production system. If it doesn't, then test logging is broken.<br /><br />Test logs should always contain: <br /><ul><li>Test execution environment</li><li>Initial state</li><li>Setup steps</li><li>Test case steps</li><li>Interactions with the system</li><li>Expected results</li><li>Actual results</li><li>Teardown steps</li></ul><br /><br /><b>Conditional Verbosity With Temporary Log Queues</b><br /><br />When errors occur, the log should contain a lot of detail. Unfortunately, detail that led to an error is often unavailable once the error is encountered. Also, if you&#8217;ve followed advice about not logging too much, your log records prior to the error record may not provide adequate detail. A good way to solve this problem is to create temporary, in-memory log queues. Throughout processing of a transaction, append verbose details about each step to the queue. If the transaction completes successfully, discard the queue and log a summary. If an error is encountered, log the content of the entire queue and the error. This technique is especially useful for test logging of system interactions.<br /><br /><br /><b>Failures and Flakiness Are Opportunities</b><br /><br />When production problems occur, you&#8217;ll obviously be focused on finding and correcting the problem, but you should also think about the logs. If you have a hard time determining the cause of an error, it's a great opportunity to improve your logging. Before fixing the problem, fix your logging so that the logs clearly show the cause. If this problem ever happens again, it&#8217;ll be much easier to identify.<br /><br />If you cannot reproduce the problem, or you have a flaky test, enhance the logs so that the problem can be tracked down when it happens again.<br /><br />Using failures to improve logging should be used throughout the development process. While writing new code, try to refrain from using debuggers and only use the logs. Do the logs describe what is going on? If not, the logging is insufficient.<br /><br /><br /><b>Might As Well Log Performance Data</b><br /><br />Logged timing data can help debug performance issues. For example, it can be very difficult to determine the cause of a timeout in a large system, unless you can trace the time spent on every significant processing step. This can be easily accomplished by logging the start and finish times of calls that can take measurable time: <br /><ul><li>Significant system calls</li><li>Network requests</li><li>CPU intensive operations</li><li>Connected device interactions</li><li>Transactions</li></ul><br /><br /><b>Following the Trail Through Many Threads and Processes</b><br /><br />You should create unique identifiers for transactions that involve processing across many threads and/or processes. The initiator of the transaction should create the ID, and it should be passed to every component that performs work for the transaction. This ID should be logged by each component when logging information about the transaction. This makes it much easier to trace a specific transaction when many transactions are being processed concurrently.<br /><br /><br /><b>Monitoring and Logging Complement Each Other</b><br /><br />A production service should have both logging and monitoring. Monitoring provides a real-time statistical summary of the system state. It can alert you if a percentage of certain request types are failing, it is experiencing unusual traffic patterns, performance is degrading, or other anomalies occur. In some cases, this information alone will clue you to the cause of a problem. However, in most cases, a monitoring alert is simply a trigger for you to start an investigation. Monitoring shows the symptoms of problems. Logs provide details and state on individual transactions, so you can fully understand the cause of problems.<br /><div><br /></div>]]></description>
				<content:encoded><![CDATA[<i>by <a href="http://www.anthonysapps.com/anthony">Anthony Vallone</a></i><br /><br />How long does it take to find the root cause of a failure in your system? Five minutes? Five days? If you answered close to five minutes, it’s very likely that your production system and tests have great logging. All too often, seemingly unessential features like logging, exception handling, and (dare I say it) testing are an implementation afterthought. Like exception handling and testing, you really need to have a strategy for logging in both your systems and your tests. Never underestimate the power of logging. With optimal logging, you can even eliminate the necessity for debuggers. Below are some guidelines that have been useful to me over the years.<br /><br /><br /><b>Channeling Goldilocks</b><br /><br />Never log too much. Massive, disk-quota burning logs are a clear indicator that little thought was put in to logging. If you log too much, you’ll need to devise complex approaches to minimize disk access, maintain log history, archive large quantities of data, and query these large sets of data. More importantly, you’ll make it very difficult to find valuable information in all the chatter.<br /><br />The only thing worse than logging too much is logging too little. There are normally two main goals of logging: help with bug investigation and event confirmation. If your log can’t explain the cause of a bug or whether a certain transaction took place, you are logging too little.<br /><br />Good things to log: <br /><ul style="line-height: 1em; margin-bottom: 0px; margin-top: 0px; padding-bottom: 0px; padding-top: 0px;"><li>Important startup configuration</li><li>Errors</li><li>Warnings</li><li>Changes to persistent data</li><li>Requests and responses between major system components</li><li>Significant state changes</li><li>User interactions</li><li>Calls with a known risk of failure</li><li>Waits on conditions that could take measurable time to satisfy</li><li>Periodic progress during long-running tasks</li><li>Significant branch points of logic and conditions that led to the branch</li><li>Summaries of processing steps or events from high level functions - Avoid logging every step of a complex process in low-level functions.</li></ul><br />Bad things to log: <br /><ul style="line-height: 1em; margin-bottom: 0px; margin-top: 0px; padding-bottom: 0px; padding-top: 0px;"><li>Function entry - Don’t log a function entry unless it is significant or logged at the debug level.</li><li>Data within a loop - Avoid logging from many iterations of a loop. It is OK to log from iterations of small loops or to log periodically from large loops.</li><li>Content of large messages or files - Truncate or summarize the data in some way that will be useful to debugging.</li><li>Benign errors - Errors that are not really errors can confuse the log reader. This sometimes happens when exception handling is part of successful execution flow.</li><li>Repetitive errors - Do not repetitively log the same or similar error. This can quickly fill a log and hide the actual cause. Frequency of error types is best handled by monitoring. Logs only need to capture detail for some of those errors.</li></ul><br /><br /><b>There is More Than One Level</b><br /><br />Don't log everything at the same log level. Most logging libraries offer several log levels, and you can enable certain levels at system startup. This provides a convenient control for log verbosity.<br /><br />The classic levels are: <br /><ul style="line-height: 1em; margin-bottom: 0px; margin-top: 0px; padding-bottom: 0px; padding-top: 0px;"><li>Debug - verbose and only useful while developing and/or debugging.</li><li>Info - the most popular level.</li><li>Warning - strange or unexpected states that are acceptable.</li><li>Error - something went wrong, but the process can recover.</li><li>Critical - the process cannot recover, and it will shutdown or restart.</li></ul><br />Practically speaking, only two log configurations are needed: <br /><ul style="line-height: 1em; margin-bottom: 0px; margin-top: 0px; padding-bottom: 0px; padding-top: 0px;"><li>Production - Every level is enabled except debug. If something goes wrong in production, the logs should reveal the cause.</li><li>Development &amp; Debug - While developing new code or trying to reproduce a production issue, enable all levels.</li></ul><br /><br /><b>Test Logs Are Important Too</b><br /><br />Log quality is equally important in test and production code. When a test fails, the log should clearly show whether the failure was a problem with the test or production system. If it doesn't, then test logging is broken.<br /><br />Test logs should always contain: <br /><ul style="line-height: 1em; margin-bottom: 0px; margin-top: 0px; padding-bottom: 0px; padding-top: 0px;"><li>Test execution environment</li><li>Initial state</li><li>Setup steps</li><li>Test case steps</li><li>Interactions with the system</li><li>Expected results</li><li>Actual results</li><li>Teardown steps</li></ul><br /><br /><b>Conditional Verbosity With Temporary Log Queues</b><br /><br />When errors occur, the log should contain a lot of detail. Unfortunately, detail that led to an error is often unavailable once the error is encountered. Also, if you’ve followed advice about not logging too much, your log records prior to the error record may not provide adequate detail. A good way to solve this problem is to create temporary, in-memory log queues. Throughout processing of a transaction, append verbose details about each step to the queue. If the transaction completes successfully, discard the queue and log a summary. If an error is encountered, log the content of the entire queue and the error. This technique is especially useful for test logging of system interactions.<br /><br /><br /><b>Failures and Flakiness Are Opportunities</b><br /><br />When production problems occur, you’ll obviously be focused on finding and correcting the problem, but you should also think about the logs. If you have a hard time determining the cause of an error, it's a great opportunity to improve your logging. Before fixing the problem, fix your logging so that the logs clearly show the cause. If this problem ever happens again, it’ll be much easier to identify.<br /><br />If you cannot reproduce the problem, or you have a flaky test, enhance the logs so that the problem can be tracked down when it happens again.<br /><br />Using failures to improve logging should be used throughout the development process. While writing new code, try to refrain from using debuggers and only use the logs. Do the logs describe what is going on? If not, the logging is insufficient.<br /><br /><br /><b>Might As Well Log Performance Data</b><br /><br />Logged timing data can help debug performance issues. For example, it can be very difficult to determine the cause of a timeout in a large system, unless you can trace the time spent on every significant processing step. This can be easily accomplished by logging the start and finish times of calls that can take measurable time: <br /><ul style="line-height: 1em; margin-bottom: 0px; margin-top: 0px; padding-bottom: 0px; padding-top: 0px;"><li>Significant system calls</li><li>Network requests</li><li>CPU intensive operations</li><li>Connected device interactions</li><li>Transactions</li></ul><br /><br /><b>Following the Trail Through Many Threads and Processes</b><br /><br />You should create unique identifiers for transactions that involve processing across many threads and/or processes. The initiator of the transaction should create the ID, and it should be passed to every component that performs work for the transaction. This ID should be logged by each component when logging information about the transaction. This makes it much easier to trace a specific transaction when many transactions are being processed concurrently.<br /><br /><br /><b>Monitoring and Logging Complement Each Other</b><br /><br />A production service should have both logging and monitoring. Monitoring provides a real-time statistical summary of the system state. It can alert you if a percentage of certain request types are failing, it is experiencing unusual traffic patterns, performance is degrading, or other anomalies occur. In some cases, this information alone will clue you to the cause of a problem. However, in most cases, a monitoring alert is simply a trigger for you to start an investigation. Monitoring shows the symptoms of problems. Logs provide details and state on individual transactions, so you can fully understand the cause of problems.<br /><div><br /></div>]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/optimal-logging/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Two New Videos About Testing at Google</title>
		<link>https://googledata.org/google-testing/two-new-videos-about-testing-at-google/</link>
		<comments>https://googledata.org/google-testing/two-new-videos-about-testing-at-google/#comments</comments>
		<pubDate>Fri, 12 Apr 2013 15:13:00 +0000</pubDate>
		<dc:creator><![CDATA[Google Testing Bloggers]]></dc:creator>
				<category><![CDATA[Google Testing]]></category>

		<guid isPermaLink="false">https://googledata.org/?guid=a889a3dd5940fa0320fe26207a56e0de</guid>
		<description><![CDATA[by <a href="http://www.anthonysapps.com/anthony">Anthony Vallone</a><br /><br />We have two excellent, new videos to share about testing at Google. If you are curious about the work that our Test Engineers (TEs) and Software Engineers in Test (SETs) do, you&#8217;ll find both of these videos very interesting.<br /><br />The  <a href="http://www.youtube.com/lifeatgoogle">Life at Google</a>  team produced a video series called  <a href="http://www.youtube.com/watch?v=eZHEnPCEe0o&#38;feature=c4-overview-vl&#38;list=PLllx_3tLoo4fd1deqnzvyZrIrJzRdSC6-">Do Cool Things That Matter</a>.  This series includes a video from an SET and TE on the Maps team (Sean Jordan and Yvette Nameth) discussing their work on the Google Maps team.<br /><br /><a href="http://www.youtube.com/watch?v=FcwMMEsRFW4&#38;list=PLllx_3tLoo4fd1deqnzvyZrIrJzRdSC6-">Meet Yvette and Sean from the Google Maps Test Team</a><br /><br /><div></div><br /><br />The  <a href="https://plus.sandbox.google.com/u/0/101571483150813305324">Google Students</a>  team hosted a  <a href="http://www.google.com/+/learnmore/hangouts/onair.html">Hangouts On Air</a>  event with several Google SETs (Diego Salas, Karin Lundberg, Jonathan Velasquez, Chaitali Narla, and Dave Chen)  discussing the SET role.<br /><br /><a href="https://plus.google.com/u/0/101571483150813305324/posts/diXcYNHmMvM">Software Engineers in Test at Google - Covering your (Code)Bases</a><br /><br /><div></div><br /><br />Interested in joining the ranks of TEs or SETs at Google? Search for <a href="http://goo.gl/I0w5J">Google test jobs</a>.<br /><br />]]></description>
				<content:encoded><![CDATA[by <a href="http://www.anthonysapps.com/anthony">Anthony Vallone</a><br /><br />We have two excellent, new videos to share about testing at Google. If you are curious about the work that our Test Engineers (TEs) and Software Engineers in Test (SETs) do, you’ll find both of these videos very interesting.<br /><br />The  <a href="http://www.youtube.com/lifeatgoogle">Life at Google</a>  team produced a video series called  <a href="http://www.youtube.com/watch?v=eZHEnPCEe0o&amp;feature=c4-overview-vl&amp;list=PLllx_3tLoo4fd1deqnzvyZrIrJzRdSC6-">Do Cool Things That Matter</a>.  This series includes a video from an SET and TE on the Maps team (Sean Jordan and Yvette Nameth) discussing their work on the Google Maps team.<br /><br /><a href="http://www.youtube.com/watch?v=FcwMMEsRFW4&amp;list=PLllx_3tLoo4fd1deqnzvyZrIrJzRdSC6-">Meet Yvette and Sean from the Google Maps Test Team</a><br /><br /><div style="text-align: center;"><iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/FcwMMEsRFW4?list=PLllx_3tLoo4fd1deqnzvyZrIrJzRdSC6-" width="560"></iframe></div><br /><br />The  <a href="https://plus.sandbox.google.com/u/0/101571483150813305324">Google Students</a>  team hosted a  <a href="http://www.google.com/+/learnmore/hangouts/onair.html">Hangouts On Air</a>  event with several Google SETs (Diego Salas, Karin Lundberg, Jonathan Velasquez, Chaitali Narla, and Dave Chen)  discussing the SET role.<br /><br /><a href="https://plus.google.com/u/0/101571483150813305324/posts/diXcYNHmMvM">Software Engineers in Test at Google - Covering your (Code)Bases</a><br /><br /><div style="text-align: center;"><iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/OZk8nlcpe3w" width="560"></iframe></div><br /><br />Interested in joining the ranks of TEs or SETs at Google? Search for <a href="http://goo.gl/I0w5J">Google test jobs</a>.<br /><br />]]></content:encoded>
			<wfw:commentRss>https://googledata.org/google-testing/two-new-videos-about-testing-at-google/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
		</item>
	</channel>
</rss>
