Keyword-driven testing library
A Keyword-driven testing library for node.
Let's write the first low-level keywords
Hello World, which prints, "Hello World" and
How are you? which prints "How are you?", obviously.
// lowlevel-keywords.jsvar lowlevelKeywords =console.log"Hello World";next;console.log"How are you?";next;;moduleexports = lowlevelKeywords;
Pretty simple stuff. Now, we can create a suite of high-level keywords.
Let's create our first high-level keyword
// highlevel-keywords.jsvar highlevelKeywords ="Greet the World":"Hello World""How are you?";moduleexports = highlevelKeywords;
Next, we want to run our keywords. Here's the code that runs the keyword
Greet the World:
// basic-example.js// Require keyword libraryvar key = require'keyword';var _ = require'underscore';// Import keyword definitions_forEachrequire'./lowlevel-keywords'keyname fn;;keysuiterequire'./highlevel-keywords';keyrun"Greet the World"then// All done.;
Now we can run the example by typing
$ node basic-example.js
> Hello World> How are you?
In basic example, all the keyword were static. They didn't take any parameter nor did they return anything.
Both, low-level and high-level keywords can take parameters and return values.
Let's define three low-level keyword:
messageas a parameter and prints it to the console log.
nameand returns a string saying "Hello" to that person.
Jointakes two strings and joins them into one string, separating by a newline
// lowlevel-keywords.jsvar lowlevelKeywords =console.logmessage;next;var returnValue = "Hello " + name;nextreturnValue;var returnValue = str1 str2join"\n";nextreturnValue;;moduleexports = lowlevelKeywords;
Alright! Our low-level keywords look a lot more general compared to the keywords in the basic example!
Now let's create some high-level keywords that give parameters to the low-level keywords, saves the return value and return something themselves.
Greet Mikko generates a greeting message for
// high-level-keywords.jsvar highlevelKeywords ="Create a greeting":"Hello" "$1" "=> $helloMikko""Join" "$helloMikko" "How are you?" "=> $return""Greet Mikko":"Create a greeting" "Mikko" "=> $greeting""Print" "$greeting";moduleexports = highlevelKeywords;
And then the
runner.js file, which is mostly the same as in the previous example
// keywords-with-parameters-example.js// Require keyword libraryvar key = require'keyword';var _ = require'underscore';// Import keyword definitions_forEachrequire'./lowlevel-keywords'keyname fn;;keysuiterequire'./highlevel-keywords';keyrun"Greet Mikko"then// All done.;
Now we can run the example by typing
$ node keywords-with-parameters-example.js
> Hello Mikko> How are you?
Ok, now you've seen how to define and use keywords, but I bet you're eager to know how does this make integration testing awesome!
Web application integration testing is usually done by threating the application as a black box which you interact through the browser. The test cases for integration tests contain a lot of repeating tasks, such as clicking an element or filling in a form, etc. These repearing tasks can be defined as a general purpose low-level keywords, such as
Navigate To URL, etc.
Imaging you're testing a social media application. Your task is to test sending message from a user Jane to user David.
First thing you have to do is to login as a Jane. This can be done by navigation to the login page (using
Navigate To URL). Then you have to fill in user credentials (using
Fill Input) and click login button (
Click). And all these you can combine and create a new high-level keyword,
After that you'll do the messaging stuff, but then you need to assert that David really got the message. So how would you do that? Well, you can use the
Login as keyword to login with David's account and see if the message arrived!
I bet you can already see the point of keywords. By defining general purpose low-level keywords, you can easily combine them and create complex high-level keywords that will make your integration testing awesome!
The library doesn't care how you interact with the browser and what is the browser you're using. You can use for example Zombie, but my favorite is to use PhantomJS via Node WebDriver.
See the Google Search example below for PhantomJS via WebDriver.
To run the example, you have to have PhantomJS running with WebDriver on port 4444. To do this, install PhantomJS and type
phantomjs --webdriver=4444 &
"use strict";// Define your keywords and test cases in JSON formatvar suite =/***** The main test case *****/"Test Google Search":"Google Search For" "keyword driven testing" "=> $searchResult""Should Equal" "$searchResult" "Keyword-driven testing - Wikipedia, the free encyclopedia"/***** Define keywords ******/"Google Search For":"Go To Page" """Fill Input By Name" "q" "$1""Click Element By Name" "btnG""Pick First Search Result" "=> $return""Pick First Search Result":"Get Text Content Of First Tag" "h3" "=> $return";// Implement your low-level keywords// This example uses WebDriver and PhantomJSvar webdriver = require'selenium-node-webdriver';var key = require'keyword';var assert = require'assert';var session = webdriver;key"Go To Page"sessionthenconsole.log"Going to" url;return drivergeturl;donenext;;key"Fill Input By Name"sessionthenreturn driverfindElementdriverwebdriverBynameelementNamesendKeystext;donenext;;key"Click Element By Name"sessionthenreturn driverfindElementdriverwebdriverBynameelementNameclick;donenext;;key"Get Text Content Of First Tag"sessionthenreturn driverexecuteScript// This script is run in browser contextreturn documentquerySelectortagtextContent;elementTagNamethenconsole.log"The first Google hit:" firstHit;return firstHit;;donenext;;key"Should Equal"console.log"Should Equal: '" + a + "' and '" + b + "'";asserta === b;next;;// Load the keywordskeysuitesuite;console.log;// Run the keywordkeyrun"Test Google Search"thenconsole.log"\nDone.\n";sessionthendriverquit;;;
cd examples/basicnpm installnode basic.js
cd examples/keywords-with-parametersnpm installnode keywords-with-parameters.js
cd examples/googlenpm installphantomjs --webdriver=4444 &node google.js
In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using grunt.
Copyright (c) 2013 Mikko Koski
Licensed under the MIT license.