27. What are SmokeTests?
In computer programming and
software testing, smoke testing is
preliminary testing to reveal simple
failures severe enough to reject a
prospective software release.
Source: https://en.wikipedia.org/wiki/Smoke_testing
29. SmokeTests should…
• … be simple
• … be fast
• … test pages with optional parameters too
• … cover at least all URLs in google index
• … use a manual maintained list of URLs
30. How do SmokeTests work?
https://www.my-application.com/foo
<html><body>…</body></html>
TTFB: 65ms
HTTP 1.1/200 OK
SmokeTest
Client
CI Server
Application
to test
Production Server
31. How do SmokeTests work?
https://www.my-application.com/foo
<html><body>…</body></html>
TTFB: 320ms
HTTP 1.1/200 OK
SmokeTest
Client
CI Server Production Server
Application
to test
32. What should SmokeTests validate?
• Status code
• Time to first byte
• If body is provided
• Correct server
33. SmokeTests are NOT Acceptance Tests
SmokeTest
Client
HTTP 1.1/200 OK
<html>
<head>
<title>Foo</title>
<body>
<div id="bar"><span>foobar</span></div>
</body>
</html>
34. namespace KartenmachereiTesting;
use PHPUnit_Framework_TestCase;
class SmokeTest extends PHPUnit_Framework_TestCase
{
/**
* @dataProvider furyUrlProvider
*
* @param Url $url
*/
public function testFuryUrl(Url $url)
{
$result = $this->sendGetRequest($url);
$this->assertSame(200, $result->getStatusCode());
$this->assertNotEmpty($result->getBody());
$this->assertLessThanOrEqual(100, $result->getTimeToFirstByteInMilliseconds());
}
public function furyUrlProvider()
{
$urls = ['http://www.kartenmacherei.de', …];
$urlCollection = UrlCollection::fromStrings($urls);
return $urlCollection->asDataProviderArray($urlCollection);
}
46. class SmokeTest extends PHPUnit_Framework_TestCase
{
use SmokeTestTrait;
/**
* @dataProvider myDataProvider
*/
public function testExample(Result $result)
{
$this->assertSuccess($result);
$this->assertTimeToFirstByte(new TimeToFirstByte(100), $result);
$this->assertBodyNotEmpty($result);
$this->assertHeaderExists(Header::fromPrimitives(‘App-Server', ‘Fury’), $result);
}
public function myDataProvider()
{
$urls = ['http://www.kartenmacherei.de', …];
$options = new SmokeTestOptions(
UrlCollection::fromStrings($urls),
new RequestTimeout(2),
new FollowRedirects(true),
new Concurrency(3),
new BodyLength(500)
);
return $this->runSmokeTests($options);
}
47. class SmokeTest extends PHPUnit_Framework_TestCase
{
use SmokeTestTrait;
/**
* @dataProvider myDataProvider
*/
public function testExample(Result $result)
{
$this->assertSuccess($result);
$this->assertTimeToFirstByte(new TimeToFirstByte(100), $result);
$this->assertBodyNotEmpty($result);
$this->assertHeaderExists(Header::fromPrimitives(‘App-Server', ‘Fury’), $result);
}
public function myDataProvider()
{
$urls = ['http://www.kartenmacherei.de', …];
$options = new SmokeTestOptions(
UrlCollection::fromStrings($urls),
new RequestTimeout(2),
new FollowRedirects(true),
new Concurrency(3),
new BodyLength(500)
);
return $this->runSmokeTests($options);
}
48. class SmokeTest extends PHPUnit_Framework_TestCase
{
use SmokeTestTrait;
/**
* @dataProvider myDataProvider
*/
public function testExample(Result $result)
{
$this->assertSuccess($result);
$this->assertTimeToFirstByte(new TimeToFirstByte(100), $result);
$this->assertBodyNotEmpty($result);
$this->assertHeaderExists(Header::fromPrimitives(‘App-Server', ‘Fury’), $result);
}
public function myDataProvider()
{
$urls = ['http://www.kartenmacherei.de', …];
$options = new SmokeTestOptions(
UrlCollection::fromStrings($urls),
new RequestTimeout(2),
new FollowRedirects(true),
new Concurrency(3),
new BodyLength(500)
);
return $this->runSmokeTests($options);
}
49. class SmokeTest extends PHPUnit_Framework_TestCase
{
use SmokeTestTrait;
/**
* @dataProvider myDataProvider
*/
public function testExample(Result $result)
{
$this->assertSuccess($result);
$this->assertTimeToFirstByte(new TimeToFirstByte(100), $result);
$this->assertBodyNotEmpty($result);
$this->assertHeaderExists(Header::fromPrimitives(‘App-Server', ‘Fury’), $result);
}
public function myDataProvider()
{
$urls = ['http://www.kartenmacherei.de', …];
$options = new SmokeTestOptions(
UrlCollection::fromStrings($urls),
new RequestTimeout(2),
new FollowRedirects(true),
new Concurrency(3),
new BodyLength(500)
);
return $this->runSmokeTests($options);
}
50. class SmokeTest extends PHPUnit_Framework_TestCase
{
use SmokeTestTrait;
/**
* @dataProvider myDataProvider
*/
public function testExample(Result $result)
{
$this->assertSuccess($result);
$this->assertTimeToFirstByte(new TimeToFirstByte(100), $result);
$this->assertBodyNotEmpty($result);
$this->assertHeaderExists(Header::fromPrimitives(‘App-Server', ‘Fury’), $result);
}
public function myDataProvider()
{
$urls = ['http://www.kartenmacherei.de', …];
$options = new SmokeTestOptions(
UrlCollection::fromStrings($urls),
new RequestTimeout(2),
new FollowRedirects(true),
new Concurrency(3),
new BodyLength(500)
);
return $this->runSmokeTests($options);
}
51. class SmokeTest extends PHPUnit_Framework_TestCase
{
use SmokeTestTrait;
/**
* @dataProvider myDataProvider
*/
public function testExample(Result $result)
{
$this->assertSuccess($result);
$this->assertTimeToFirstByte(new TimeToFirstByte(100), $result);
$this->assertBodyNotEmpty($result);
$this->assertHeaderExists(Header::fromPrimitives(‘App-Server', ‘Fury’), $result);
}
public function myDataProvider()
{
$urls = ['http://www.kartenmacherei.de', …];
$options = new SmokeTestOptions(
UrlCollection::fromStrings($urls),
new RequestTimeout(2),
new FollowRedirects(true),
new Concurrency(3),
new BodyLength(500)
);
return $this->runSmokeTests($options);
}
53. Features to come next
• Improve ErrorResult object
• Introduce assertions for Redirects
• Improve quality of error message
• 2nd version based on PHPUnit 6
59. RDBMS
Read Slave
Webserver
FURY Frontend
Server A
K/V StoreSearch
FURY Backend
Webserver (Router)
Build Server
Deploy Code
active = B
60. RDBMS
Read Slave
Webserver
FURY Frontend
Server A
K/V StoreSearch
FURY Backend
Webserver (Router)
Build Server
Deploy Code
Collect & Export
active = B
61. Webserver
FURY Frontend
Server A
K/V StoreSearch
FURY Backend
Webserver (Router)
Build Server
Deploy Code
Collect & Export
Smoke Tests
active = B
RDBMS
Read Slave
62. Webserver
FURY Frontend
Server A
K/V StoreSearch
FURY Backend
Webserver (Router)
Build Server
Deploy Code
Collect & Export
Smoke Tests
active = B
RDBMS
Read Slave
63. Webserver
FURY Frontend
Server A
K/V StoreSearch
FURY Backend
Webserver (Router)
Build Server
Deploy Code
Collect & Export
Smoke Tests
active = B
RDBMS
Read Slave
64. Webserver
FURY Frontend
Server A
K/V StoreSearch
FURY Backend
Webserver (Router)
Build Server
Deploy Code
Collect & Export
Smoke Tests
Switch to A
active = Bactive = A
RDBMS
Read Slave
65. Conclusion
• Write tests
• Get 100% coverage
• SmokeTest your Website
• Only activate server if it didn’t start smoking