Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Smashtest Tutorial: Run Your Automation Script 10x Faster

DZone 's Guide to

Smashtest Tutorial: Run Your Automation Script 10x Faster

A guide.

· Performance Zone ·
Free Resource

Image title

Soon your automation will be running at top speed!


When it comes to automated website testing, one extremely important parameter is the intellect gathered from the output of your automation test execution i.e. the number of bugs reported, percentage of pass/failed test cases, test coverage, etc. If there are frequent releases in your project, the throughput achieved via testing can be adversely affected if the tests are performed frequently. The down-side of less frequent testing is that the bugs might be unearthed during the later stages of development which can postpone the product release. At some point in time, the test team will integrate Automation testing as part of the testing phase so that throughput can be improved and manual resources can be used for some other tasks.

Have you heard? There is a new language in the town! This programming language is called Smashtest and is specifically designed for automation testers to help them automate their test cycles up to ten times faster. Interesting, isn’t it?

In this article, I will help you walk through the entire process of running automation testing with Selenium using the Smashtest. This is going to be a rather lengthy journey but by the time we are done, you will be writing test cases in a jiffy. Below is an image of an example test from Smashtest’s official website.

smashtest

See how easy it is going to be? Now, without further ado, let us get started.

You may also like: Running Fast SQL on DynamoDB Tables  

Automation Testing With Selenium

Automation testing with Selenium is very popular since many popular programming languages (Python, C#, Java, PERL, etc.) can be used with that framework. Automation tests require more advanced infrastructure than manual tests since the tests might be performed in parallel to maximize the throughput. When it comes to testing of web products, automated cross-browser testing becomes important as the behavior may not be the same on different browsers, operating systems, and devices. For example, a web page may render correctly on Chrome installed on Windows but might not render properly on Chrome installed on macOS.

In the past we have covered several topics related to automation testing with the Selenium framework, many of them focused on performance, parallel testing, detailed reporting, etc. You can check them out through our Selenium tutorials. The duration taken by the tests to execute not only depends on the efficiency of the test cases (from an implementation point of view) but also depends on the infrastructure on which the tests are being executed. A very-well written test can take more time to execute if executed on a less powerful machine.

Though you can make use of cloud-based infrastructure for automated cross-browser testing, wouldn’t it better if the overall performance of automation testing with Selenium can be enhanced for rapidly deploying test cases. This is where Smashtest steps in to help you test even faster.

Smashtest – Develop and Deploy Test Cases Rapidly

smashtest1

Smashtest is a programming language that allows you to speed up your automation testing cycle by writing tests in a tree-like format.

Trees loosely represent the thinking in writing a test case/test scenario. For example, the task ‘Open google.com in Chrome web browser’ is written as the following in Smashtest programming language.

Open Chrome Navigate to 'google.com' 

As programming instructions in Smashtest are simple English statements; it becomes easier to rapidly describe and deploy your test cases.

Here are some of the advantages of using Smashtest:

  • Automation testing on multiple browsers and devices.
  • UI and API level testing.
  • Run multiple tests in parallel.
  • Live reports that detail the execution result at each step.
  • Easy to understand and human-readable steps.
  • Tests that can be executed locally or in the CI/CD pipeline.

Now, we will dig deep into Smashtest programming language and how it can be used in collaboration with Selenium for automated cross-browser testing scenarios.

Setup and Prerequisites

1. NodeJS — Smashtest makes use of NodeJS. It is required to execute the NPM (Node Package Manager) command through which the SmashTest package is installed. NPM is a package manager for Node.js with thousands of packages. NodeJS can be downloaded from here.

2. Selenium WebDriver — As automated cross-browser testing with Smashtest makes use of the Selenium framework, it is important to have the Selenium WebDrivers in place before testing. Selenium WebDriver for popular browsers like Internet Explorer, Chrome, Firefox, Microsoft Edge, etc. can be downloaded from the locations mentioned below:

BROWSER DOWNLOAD LOCATION
Opera https://github.com/operasoftware/operachromiumdriver/releases
Firefox https://github.com/mozilla/geckodriver/releases
Chrome http://chromedriver.chromium.org/downloads
Internet Explorer https://github.com/SeleniumHQ/selenium/wiki/InternetExplorerDriver
Microsoft Edge https://blogs.windows.com/msedgedev/2015/07/23/bringing-automated-testing-to-microsoft-edge-through-webdriver/

Once the WebDriver is downloaded, the same should be placed in your system’s PATH (C:\Windows\system32 on Windows and  /usr/local/bin on Linux and macOS). You can also copy the corresponding WebDriver in the directory from where the test is being performed.

Read More: Selenium WebDriver Tutorial For Cross Browser Testing

3. Smashtest — As NodeJS is already installed, you can install Smashtest using the NPM command. You can execute the following command from the terminal to install Smashtest.

npm install smashtest // Use sudo in case you get permission issue sudo npm install smashtest

4. Install Grammar for Smashtest — As Smashtest is a different programming language, you need to install the corresponding grammar which will highlight the code and makes the coding job using Smashtest more comfortable. VSCode and Atom are the two IDEs on which Smashtest grammar is available.

5. VSCode — Visual Studio Code (VSCode) from Microsoft is the source-code editor for Windows, Linux, and macOS. VSCode can be downloaded from here. Once VSCode is installed, you should install the Smashtest language support from here. Alternately, you can also download the Smashtest language support extension by visiting the Extensions MarketPlace from the VSCode IDE.

Smashtest language

6. Atom — Atom can be downloaded from here. Once installed, you should download & install the Smashtest package from here. To enable the configuration of smash files (.smash), make sure to follow the below steps:

  • Ctrl/Cmd + Shift + P in the Atom IDE.
  • Type open config and hit enter. This command will open the config.cson file.
  • Now, you would need to add the following piece of code to the bottom of the file.
".smash.source": editor:     
autoIndentOnPaste: false     
  commentStart: "//"     
    tabLength: 4


For development, we will make use of the VSCode IDE installed on Windows 10. We have a look at the coding practices used when programming with Smashtest and some of the frequently used commands/instructions.

Smashtest — Language and Instruction Set

It doesn’t matter if you are using Smashtest for automated cross-browser testing or some other automation testing, one thing that needs to be looked at is the indentation of the source code. One additional indent can lead to the instruction/statement being executed in the next branch.

Best Practices For Writing Automation Scripts In SmashTest

Here are some of the best practices that should be followed when programming with SmashTest.

Indents — Spaces (no tabs) should be used for indentation. Four spaces to be used for each indent. In the example shown below, four instructions [Instruction 1 ~ Instruction 4] will be executed as a part of branch-1 whereas Instruction 5 will be executed as a part of branch-2

Instruction 1     
  Instruction 2         
  Instruction 3             
  Instruction 4 
Instruction 5


Blank Lines — Blank lines should be used for code organization and grouping similar steps. Blank lines should be used with utmost care in a Step Block. A step block should not have blank lines between members whereas the blank line should be used if it has children.

In the example below, the Lambdatest homepage would be opened on three browsers — Chrome, Firefox, and Edge.

Open Chrome     
//step block Open Firefox Open Edge     
Navigate to 'lambdatest.com'


Scope — During runtime, all the files that are passed to SmashTest are concatenated in one long piece of text. Everything declared at indent 0 is accessible in all other .smash files.

// a.smash // ----------- 
* Open google     
Navigate to 'google.com'         
  Click '.gNO89b'


// b.smash // ----------- 
Open Chrome     
Open google   // declared in a.smash


In the example shown above, a function Open google is declared in a.smash and the same is accessible from b.smash.

Step Blocks

There are two types of step blocks — simple step block and multi-level step block. We have already covered an example of simple step block where navigation to lambdatest.com will be performed on Chrome and Edge browsers as shown below

Open Chrome     
//step block 
Open Firefox 
Open Edge     
Navigate to 'lambdatest.com'


Multi-level step blocks can be with/without an identifier/label. The commands after a multi-level step block are repeated for each branch. As shown in the example below, we navigate to google.com and perform a search for Lambdatest and Testing in two separate operations. We also name the multi-level step for easier identification.

open chrome     
navigate to 'google.com'         
  // Naming the search block for easier identification         
  enter search criteria [             
  type 'Lambdatest[enter]' 
  into 'input[name=q]'             
  type 'Testing' into 'input[name=q]'                 
  click 'search'         ]             
  // This operation will be performed for both the search operations             
  verify search results


The operation verifies search results will be performed after both the searches. The block is named as entering search criteria for easy identification.

Functions

Functions that are declared at indentation 0 can be accessed by all the steps under that parent. The function can also be used in other .smash files. Like other programming languages, function calls can be used with & without input parameters. Input parameters can be a combination of strings, variables, etc. Examples of function calls are below:

Function call 1     
  Function call 2 with 'strings' and "strings" and [strings] as inputs         
  Function call 3 with {variables} and {{variables}} as inputs             
  Function call 4 with '{variables} inside strings' as inputs


Functions declarations can be public, have inputs, have brackets, have branches, etc. A sample function declaration is below:

Public Declaration

* Public Function declaration     
Navigate to 'xyz.com'         
  Click 'button' // This function call with navigate to the website and clicks button Function declaration here


With Bracket

* Search operation [     
  Navigate to 'searchengine.com'         
  Type 'search-term' into 'search-box'             
  Click 'search button' ]


With Input Arguments

// Input arguments should always be {{local variables}} * 
Function declaration that {{takes}} in {{input-arguments}}     
Navigate to 'xyz.com/{{takes}}/{{input-arguments}}'         
  Click 'search button' // Function call Function declaration that 'input string' in {input variable}


There are many other ways in which function declaration can be done however; covering all those variants is beyond the scope of this article. While performing automation testing with Selenium, you can use these options for function declarations or the ones mentioned in the functions section of Smashtest.io.

Variables

Like other programming languages, variables in Smashtest programming can be local, global, and persistent.

Global variables — Global variables as we are already aware are mostly declared over the top of your program and can be accessed from inside and outside of function calls. Offering a global scope, these variables are made accessible for every step derived from the rest of the branch.

{variable} = 'some-variable'   // variable scope is global     
  F * F     Type {variable} into 'text-box'   // accessing the variable


Local Variables — These variables have a local scope which means that the variables are only accessible from within the functional call.

{{variable}} = 'some-string-value'   // local variable declaration     
  F         
  Type {{variable}} into 'some-textbox' * F     
  // Type {{variable}} into 'some-textbox'   
  // Unlike global variables, local variables are not accessible here


Code Blocks

You can have code blocks through which you can pass variables between different functions, raise assert, take actions when errors are encountered (normal error, Error.continue, Error.fatal), capture stack trace, etc.

Statements/Instructions between { } are considered a part of the code block. The important thing to note is that the start and end indentation of the code block should be the same.

* Function name {     
  // Operations supported by js and nodejs can be added here.     
  // Match the indentation of the closing brace with the opening brace }


You can also have Steps for one-time execution which can supersede or precede a code block.

Name of the step {     
  // Step implementation     
  // Called only once }


Errors (Normal Error)

Step that is failing {     
  throw new Error("error message here");   
  // assert is raised and the execution ends here }


Errors (Error.continue)

Step that is failing {     
  let err = new Error("verification failed but we still continue the execution");     
  err.continue = true;   // Step failure happends here and it will branch     
  throw err;             // The branch will continue running/executing }


Errors (Error.fatal)

Failing step {     
  let err = new Error("error has occured");     
  err.fatal = true;   // test execution ends here     
  throw err; }


Comments

Comments can be added inside the code blocks and can also be added to ignore lines. The core fundamentals of comments in Smashtest programming language are the same as in other programming languages.

Standard comments

// comment - This line will be ignored Step   // Comment to explain the purpose of the implementation


Comments Inside code blocks

Piece of code {     /* Implementation here */ }


Groups and Freq (#)

Group is used to execute test cases that are grouped under a label. There are built-in groups as well as user-defined groups. Groups are useful when you have to execute a certain set of test cases from the test case/test suite.

Open Chrome 
Open Safari     
Navigate to 'duckduckgo.com'    #duckduckgo #search         
    // perform search on duckduckgo     
    Navigate to 'google.com'        #google #search         
    // perform search google


Built-in group Safari can be executed using the following command

smashtest --groups=safari

Implementation under duckduckgo and search branches can be executed using the following command

smashtest --groups=”duckduckgo, search”

Frequency is used when you want to execute test cases as per priority. For example, when doing automated cross-browser testing; you may want to execute test cases on browsers that are considered high priority and rest can be considered either medium priority. This option can be used in automation testing with Selenium to make sure that time & resources are spent on test cases that matter the most.

Open Edge
Navigate to 'duckduckgo.com'
  Priority-1 test case #high   // can be used for smoke tests         
  Priority-2 test case #med   // normal test suites         
  Priority-2.1 test case // default priority - #med         
  Lowest priority test cases  #low


Conditional Tests

Conditional tests can be used if you plan to execute tests based on some conditions. if..else, if the browser is, and if the viewport is are some of the ways through which you can achieve conditional testing based on conditions, browser type, and device type respectively.

Open Edge     
Navigate to 'duckduckgo.com'         
  Priority-1 test case #high   // can be used for smoke tests         
  Priority-2 test case #med   // normal test suites         
  Priority-2.1 test case      // default priority - #med         
  Lowest priority test cases  #low


If Step


If cond_1 then cond_2 {     if (cond_1) {         cond_2();     } }


If the Browser Is

Do something 
Do not allow Edge { if(browser.params.name == 'Edge') { 
// Enters here only if the browser is Edge } } 
- Enters here only if the browser is not Edge


If Viewport Is

Do something     
if Desktop {         
if(!runInstance.currBranch.groups.includes('desktop')) 
{             runInstance.currBranch.markBranch('pass');         }     }         
- Enters here only if the viewport is desktop


Collapse and Hidden (+, +?)

As the symbol signifies, the content i.e. function calls, prints, etc. inside the collapse sign (+), will be disintegrated by default, during the time of report generation. The content inside the collapse sign automatically un-collapses if there is an error or the function is currently in execution.

* Some operation on text box +  // This will be collapsed in the report     
  Click 'text box'         // Do something Collapse-2 +   
  // This will also be collapsed in the report

Function calls within the Hidden symbol (+?) will stay hidden in the report. Similar to the Collapse symbol, in case there is an error while executing the function within the +? symbol; the content will be made visible in the generated report.

* Function_1 +?   // calls here will be hidden     
  Do something This will also be hidden in the repotr +?


Debug (~ and ~~)

Normal Debug modifier and Express debug modifier are the two types of debug modifiers. In a normal debug modifier, the testing is paused depending on where the debug symbol (~) is used i.e. leading or trailing to a statement.

// Example of Debug Modifier used as Leading debug symbol Navigate to 'duckduckgo.com'    
~ Click 'something'   
// Leading debug symbol - isolate this branch, run in REPL, and pause before this step     
  Click 'some other thing' // Example of Debug Modifier used as Trailing debug symbol 
  Navigate to 'duckduckgo.com'     
  Click 'something' ~  // Trailing debug symbol - isolate this branch, run in REPL, and pause after this step     
  Click 'some other thing'


In express debug modifier (~~), execution does not pause when the ~~ symbol is encountered since it doesn’t run in REPL (read–eval–print loop).

Navigate to 'duckduckgo.com'     
  ~~ Click 'some thing'   // only run this branch, no pausing and don't run in REPL (read–eval–print loop)     
  Click 'some other thing'


There are many other options like Hooks (***), Sequential (..), Non-parallel (!, !!), etc. that can be used with the Smashtest programming language, however covering every option is beyond the scope of this article. You can refer to the Language section of Smashtest for more information.

Conclusion

Smashtest programming language can accelerate test execution since the tests can be rapidly deployed. Since it supports the Selenium testing framework, automated cross-browser testing can be done using Smashtest and Selenium.


Further Reading

A Complete Guide For Your First TestNG Automation Script

Transform Manual Test Scripts to Automation for Better Test Coverage

Topics:
selenium automation ,selenium - web browser automation ,selenium scripts ,selenium automation testing ,automated browser testing ,selenium test automation ,selenium tutorials ,tutorial ,performance

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}