Technical Test Creation Guidelines

Technical Test Creation Guidelines

Helpful Definitions

  • Test category - A test category is a grouping of related tests (subtests) that all test against the same vulnerability. For example, the category may be SQL Injection, Cross Site Scripting (XSS), Authentication, etc.

  • Test / Subtest - This is a specific method to attack or exploit some vulnerability on the system. Each test has its own CVSS score.

  • Steps - Given, When, Then, And, But

  • CVSS - Common Vulnerability Scoring System

  • Gherkin is a syntax using “Given,” “When,” and “Then” steps to write plain English.

  • Behavior-Driven Development (BDD) is a system of describing the behavior of a system in plain English.

  • Feature files (.feature) use the Gherkin syntax to write security tests in a BDD style.

  • PyTest files (.py with prefix of “test_”) use decorators in Python to connect the plain English of the feature file to an actual implementation of code.

  • Playwright is a PyTest plugin used to tests websites.

Creating a Test

  1. Pick a specific test and test category to add to the OpenMRS system.

    1. Make sure to review the dashboard or the tests/ subdirectories to ensure you are not recreating an existing test.

  2. Decide whether the test you are writing already has a created category.

    1. If it does (in the form of a feature file and directory) then skip to step 9, where a new scenario is added.

    2. If it doesn’t, then continue following these steps.

  3. Copy the example_category/ folder and paste it in the tests/ subdirectory

  4. Rename the copy to the test category

  5. Rename the example.feature file to <test_category>.feature

  6. We will rename the test_example.py test file later.

  7. At this point, each file has boilerplate and comments to help guide you through writing each file. Even so, the following will go through how to write each portion.

 

__init__.py

  1. The __init__.py file does not need to be edited. Its function is to allow python to treat the entire project as a package, which allows importing files in different directories. Do not edit this.

 

example.feature

  1. Here are the sections of the feature file that will need to be filled out.

    1. Feature: The Feature describes a vulnerability or test category that a user is testing. For example, XSS, SQL Injection, etc. In this way, it groups related scenarios, or related tests.

    2. Background: Background holds any amount of Given steps to run before each scenario. These should be used to consolidate shared behavior.

    3. Given: Given steps are used to describe the initial context of the system. This will run before the test and sets up the system to be in a known state. Such as, "Given I am logged in" When written in the background, the Given will run before each scenario.

    4. Scenario: A scenario is a specific method to test against the vulnerability. Each scenario will be converted into its own test file in Python.

      1. Make sure to give the Scenario a description underneath it. This will be what the dashboard reads in as the description.

      2. Given: See above description.

      3. When: The attacker tries some attack method,

      4. Then: The system should do this in response as a proper defense.

        1. The “Then” step should be specific and mention how something is done, but not delve too much into implementation.

        2. A good example is “Then the user should be on the login page” and not “Then the authentication test was properly defended.” The latter can be assumed, as that is the point of the “Then” step and it gives no explanation for how the system is defended.

      5. And: The system may optionally do this. Any amount of “And’s” may be used.

  2. Here is how the feature file is able to integrate with the dashboard

    1. The “Given a CVSS score is calculated and printed” step is automatically in the feature file and the test file. This should always be kept in. It allows the dashboard to access a specific test’s CVSS score and severity.

    2. The feature text will become the category in the dashboard.

    3. The scenario text will become the test name in the dashboard.

    4. The text directly under the scenario will become the test description in the dashboard.

 

test_example.py

  1. For each scenario written, a corresponding test file will need to be made. Simply copy and paste this test_example.py for more than one test.

  2. Rename this file to test_<scenario description>.py

    1. It is important to keep the prefix test_, or pytest will not run the test.

  3. In this file, it explains how to choose the CVSS scores, as well as how to connect each step in the feature file to the py file.

  4. Each decorator, starting with @pytest_bdd.<step>(‘’) needs the corresponding text of that step inside of the quotes exactly. Copy and pasting from the feature file is recommended.

  5. Under each decorator, the functions should be renamed to reflect what is happening in the step above.

    1. Note that the scenario’s function name must start with test_.

    2. As well, It is important that each scenario function name must be unique or else pytest will confuse them and the results may be invalid.

  6. To pick the CVSS score, follow along with the descriptions in the Given function. For supplementary guidance, see also https://www.first.org/cvss/v4.0/specification-document

  7. If any steps are repeated from another scenario, like if two scenarios share the same given statement, then it can be removed from the specific py files and added to the directory’s conftest.py file. See below.

 

conftest.py

  1. For any shared steps that have the same implementation, put them in this conftest file. When pytest runs, it will be able to figure out what to run based on the pytest_bdd decorators.

  2. If a step is shared outside of the feature file, meaning two different feature files share a step, then that step can be added to the conftest.py file in the tests/ directory.

  3. Do not put the CVSS step in here because its implementation should be different for each scenario. Even if it is the same for a subset of scenarios, keep in mind that if a new scenario is added in the future, it may have a different CVSS score.

  4. As well, fixtures can be added here or in the specific test file to hold information between steps. Please seek further documentation for information about this feature.

  5. For more utilization of pytest’s and bdd’s features, see also pytest hooks and parametrized steps. Please seek further documentation for information about these features.