Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Night Watch with QA
Search
Carsten Sandtner
October 24, 2016
Technology
0
80
Night Watch with QA
My slides for my talk at WebTech Conference in Munich, October 2016.
Carsten Sandtner
October 24, 2016
Tweet
Share
More Decks by Carsten Sandtner
See All by Carsten Sandtner
THE AI THAT WENT OUT TO DESTROY MANKIND
casarock
0
270
Over Mt. Stupid to Deep Learning
casarock
0
380
Mixed Realities for Web
casarock
0
320
Everything Web! And why OPEN matters
casarock
0
12
Mixed Realities in your browsers - BEDCon 2018
casarock
0
90
Mixed Realities in your browsers
casarock
1
540
WebVR - Virtual Reality in your browsers
casarock
0
140
Everything web and why open matters
casarock
0
270
WebVR - Virtual Realities in your Browsers
casarock
0
140
Other Decks in Technology
See All in Technology
業務効率化をさらに加速させる、ノーコードツールとStep Functionsのハイブリッド化
smt7174
2
130
能登半島災害現場エンジニアクロストーク 【JAWS FESTA 2025 in 金沢】
ditccsugii
0
570
Git in Team
kawaguti
PRO
3
360
ガバメントクラウドの概要と自治体事例(名古屋市)
techniczna
2
230
Node.js 2025: What's new and what's next
ruyadorno
0
100
許しとアジャイル
jnuank
1
150
Simplifying Cloud Native app testing across environments with Dapr and Microcks
salaboy
0
150
社内報はAIにやらせよう / Let AI handle the company newsletter
saka2jp
8
1.4k
Exadata Database Service on Dedicated Infrastructure(ExaDB-D) UI スクリーン・キャプチャ集
oracle4engineer
PRO
3
5.5k
Adapty_東京AI祭ハッカソン2025ピッチスライド
shinoyamada
0
280
神回のメカニズムと再現方法/Mechanisms and Playbook for Kamikai scrumat2025
moriyuya
4
730
大規模サーバーレスAPIの堅牢性・信頼性設計 〜AWSのベストプラクティスから始まる現実的制約との向き合い方〜
maimyyym
9
4.4k
Featured
See All Featured
BBQ
matthewcrist
89
9.8k
Keith and Marios Guide to Fast Websites
keithpitt
411
23k
Done Done
chrislema
185
16k
Site-Speed That Sticks
csswizardry
11
900
The Straight Up "How To Draw Better" Workshop
denniskardys
238
140k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
285
14k
Become a Pro
speakerdeck
PRO
29
5.5k
Build your cross-platform service in a week with App Engine
jlugia
232
18k
Code Review Best Practice
trishagee
72
19k
Unsuck your backbone
ammeep
671
58k
jQuery: Nuts, Bolts and Bling
dougneiner
65
7.9k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
252
21k
Transcript
Night watch …with QA Carsten Sandtner (@casarock) mediaman// Gesellschaft für
Kommunikation mbH
about:me Carsten Sandtner @casarock Head of Software Development //mediaman GmbH
None
Testing
Unit Tests
Integration Tests
System Tests National Museum of American History Smithsonian Institution -
https://flic.kr/p/e6s1Lr
User Acceptance Tests Brett Jordan - https://flic.kr/p/7ZRSzA
UAT System Test Integration Test Unit Test Preliminary design Detailed
design Implementation Requirements
UAT Integration Test Unit Test Detailed design Implementation Requirements System
Test Preliminary design
by 7263255 - https://flic.kr/p/6YgDNN
None
None
Testing pyramid # of Tests easy to automate
Implementation Unit Test TDD
Integration Test Unit Test Detailed design Implementation Unit Test
System Test Integration Test Unit Test Preliminary design Detailed design
Implementation
Automated E2E Test
None
None
None
– http://nightwatchjs.org/ „Nightwatch.js is an easy to use Node.js based
End- to-End (E2E) testing solution for browser based apps and websites. It uses the powerful Selenium WebDriver API to perform commands and assertions on DOM elements.“
Nightwatch & WebDriver
Features • Clean syntax • Build-in test runner • support
for CSS and Xpath Selectors • Grouping and filtering of Tests • Saucelab and Browserstack support • Extendable (Custom Commands) • CI support!
Installation $ npm install [-g] nightwatch … and Download Selenium-Server-Standalone!
Done.
Nightwatch project structure ├──bin/ | ├──chromedriver | └──seleniumdriver.jar | ├──data/
| └──globals.js | ├──reports/ | └──fancyreports.xml | ├──tests/ | ├──meaningfultest1.js | ├──meaningfultest2.js | └── … └──nightwatch.js[on]
Nightwatch.js module.exports = { "src_folders": ["tests"], "output_folder": "reports", "custom_commands_path": "",
"custom_assertions_path": "", "page_objects_path": "./objects/", "globals_path": "", "selenium": { "start_process": true, "server_path": "bin/selenium-server-standalone-2.53.1.jar", "log_path": "", "host": "127.0.0.1", "port": 4444, "cli_args": { "webdriver.chrome.driver": "./bin/chromedriver", "webdriver.ie.driver": "", "webdriver.gecko.driver" : "./bin/geckodriver090" } },
Nightwatch.js - Test setup. "test_settings": { "default": { "launch_url": "http://localhost",
"selenium_port": 4444, "selenium_host": "localhost", "silent": true, "screenshots": { "enabled": false, "path": "" }, "desiredCapabilities": { "browserName": "chrome", "marionette": true } }, “staging“: { . . . },
Nightwatch.js - Browser setup "chrome": { "desiredCapabilities": { "browserName": "chrome",
"javascriptEnabled": true, "acceptSslCerts": true } } } };
Simple Nightwatch test module.exports = { 'Google Webtechcon' : function
(client) { client .url('http://www.google.com') .waitForElementVisible('body', 1000) .assert.title('Google') .assert.visible('input[type=text]') .setValue('input[type=text]', 'webtechcon') .waitForElementVisible('button[name=btnG]', 1000) .click('button[name=btnG]') .pause(1000) .assert.containsText('#rso > div.g > div > div > h3 > a', 'WebTech Conference 2016') .end(); } };
Test execution $ nightwatch [-c nightwatch.js] tests/simplegoogle.js
None
Tests in detail
Arrange and assert module.exports = { 'Google Webtechcon' : function
(client) { client .url('http://www.google.com') .waitForElementVisible('body', 1000) .assert.title('Google') .assert.visible('input[type=text]') .end(); } }; arrange assert
Arrange, action and assert module.exports = { 'Google Webtechcon' :
function (client) { client .url('http://www.google.com') .waitForElementVisible('body', 1000) .assert.title('Google') .assert.visible('input[type=text]') .setValue('input[type=text]', 'webtechcon') .waitForElementVisible('button[name=btnG]', 1000) .click('button[name=btnG]') .pause(1000) .assert.containsText('#rso > div.g > div > div > h3 > a', 'WebTech Conference 2016') .end(); } arrange assert assert action
Hardcoded values?
Hardcoded values module.exports = { 'Google Webtechcon' : function (client)
{ client .url('http://www.google.com') .waitForElementVisible('body', 1000) .assert.title('Google') .assert.visible('input[type=text]') .end(); } };
Using globals module.exports = { 'Google Webtechcon' : function (client)
{ var globals = client.globals; client .url(globals.url) .waitForElementVisible('body', 1000) .assert.title(globals.static.pageTitle) .assert.visible(globals.selectors.searchField) .end(); } };
Define globals module.exports = { url: 'http://www.google.com', selectors: { 'searchField':
'input[type=text]' }, static: { 'pageTitle': 'Google' } } Save as data/google.js
Add to config (test-settings) module.exports = { . . .
"test_settings": { "default": { "launch_url": "http://localhost", "selenium_port": 4444, "selenium_host": "localhost", "silent": true, "screenshots": { "enabled": false, "path": "" }, "desiredCapabilities": { "browserName": "chrome", "marionette": true }, "globals": require('./data/google') }, . . .
None
Use Page Objects!
Using Page Objects module.exports = { 'url': 'http://www.google.com', 'elements': {
'searchField': 'input[type=text]' } }; Save as object/google.js
Add objects to config module.exports = { "src_folders": ["tests"], "output_folder":
"reports", "custom_commands_path": "", "custom_assertions_path": "", "page_objects_path": "./objects/", "globals_path": "", "selenium": {. . .}, "test_settings": {. . .} };
Add objects to config module.exports = { 'Google Webtechcon' :
function (client) { var googlePage = client.page.google(), globals = client.globals; googlePage.navigate() .waitForElementVisible('body', 1000) .assert.title(globals.static.pageTitle) .assert.visible('@searchField') .end(); } };
More PageObjects awesomeness module.exports = { 'url': 'http://www.some.url', 'elements': {
'passwordField': 'input[type=text]', 'usernameField': 'input[type=password]', 'submit': 'input[type=submit]' }, commands: [{ signInAsAdmin: function() { return this.setValue('@usernameField', 'admin') .setValue('@passwordField', 'password') .click('@submit'); } }] };
In your test module.exports = { 'Admin log in' :
function (browser) { var login = browser.page.admin.login(); login.navigate() .signInAsAdmin(); browser.end(); } };
Grouping tests $ nightwatch --group smoketests $ nightwatch --skipgroup smoketests
$ nightwatch --skipgroup login,whatever
Test groups | ├──tests/ | ├──smoketests/ | | ├──meaningfulTest1.js |
| ├──meaningfulTest2.js | | └── …… | └──login/ | ├──authAndLogin.js | └── ……
Tag your tests $ nightwatch --tag login $ nightwatch --tag
login --tag something_else $ nightwatch --skiptags login $ nightwatch --skiptags login,something_else
In your test module.exports = { '@tags': ['login', 'sanity'], 'Admin
log in' : function (browser) { var login = browser.page.admin.login(); login.navigate() .signInAsAdmin(); browser.end(); } };
Demo
Nightwatch is extendable! • Write custom commands • add custom
assertions • write custom reporter
Nightwatch is Javascript! • Using Filereaders • CSV, Excel etc.
• write helpers if needed!
None
Nightwatch @Mediaman
The problem
Before Nightwatch
The solution
UAT System Test Integration Test Unit Test Preliminary design Detailed
design Implementation Requirements ✓ ✓ ✓ ✓ ✓ ✓
Thanks! Carsten Sandtner @casarock
[email protected]
https://github.com/casarock (◡‿◡✿)