summaryrefslogtreecommitdiff
path: root/automated/doc/test-writting-guidelines.rst
blob: eb422f6cf2bdd5e7256de193349a8602b5d996b4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
=======================
Test Writing Guidelines
=======================

This document describes guidelines and is intended for anybody who wants to write
or modify a test case. It's not a definitive guide and it's not, by any means, a
substitute for common sense.

General Rules
=============

1. Simplicity
-------------

It's worth keeping test cases as simple as possible.

2. Code duplication
-------------------

Whenever you are about to copy a large part of the code from one test case to
another, think if it is possible to move it to a library to reduce code
duplication and the cost of maintenance.

3. Coding style
---------------

Use common sense and BE CONSISTENT.

If you are editing code, take a few minutes to look at the code around you and
determine its style.

The point of having style guidelines is to have a common vocabulary of coding so
people can concentrate on what you are saying, rather than on how you are saying
it.

3.1 Shell coding style
~~~~~~~~~~~~~~~~~~~~~~
When writing test cases in shell write in *portable shell* only.

You can either try to run the test cases on Debian which has '/bin/sh' pointing
to 'dash' by default or install 'dash' on your favorite distribution and use
it to run the tests.

Ref: `Shell Style Guide <https://google.github.io/styleguide/shell.xml>`_

3.2 Python coding style
~~~~~~~~~~~~~~~~~~~~~~~
Please follow PEP 8 style guide whenever possible.

Ref: `PEP 8 <https://www.python.org/dev/peps/pep-0008/>`_
Easy-to-read version of PEP 8 available at `pep8.org <http://pep8.org>`_

4. Commenting code
------------------

Use useful comments in your program to explain:

    * assumptions
    * important decisions
    * important details
    * problems you're trying to solve
    * problems you're trying to overcome in your program, etc.

Code tells you how, comments should tell you why.

5. License
----------
Code contributed to this repository should be licensed under GPLv2+ (GNU GPL
version 2 or any later version).

Writing a test case
===================

Linux
------

1. Structure
~~~~~~~~~~~~

Tests are generally placed under 'linux/' directory. Everything that relates to
the test goes under the same folder named with test case name.

Define 'linux/test-case-name/output' folder in test case to save test output and
result. Using a dedicated folder is helpful to distinguish between test script
and test output.

2. Installing dependencies
~~~~~~~~~~~~~~~~~~~~~~~~~~

The same test case should work on Debian/Ubuntu, Fedora/CentOS and OE based
distributions whenever possible. This can be achieved with install_deps()
function. The following is a simple example. "${SKIP_INSTALL}" should be set to
'true' on distributions that do not supported install_deps(). In the unsupported
case, if "${SKIP_INSTALL}" is 'true', install_deps() still will skip package
installation.

Example 1::

    install_deps "${pkgs}" "${SKIP_INSTALL}"

Package name may vary by distribution. In this case, you will need to handle
package installation with separate lines. dist_name() function is designed to
detect the distribution ID at running time so that you can define package name
by distribution. Refer to the following example.

Example 2::

    dist_name
    case "${dist}" in
      debian|ubuntu) install_deps "lsb-release" "${SKIP_INSTALL}" ;;
      fedora|centos) install_deps "redhat-lsb-core" "${SKIP_INSTALL}" ;;
      unknown) warn_msg "Unsupported distro: package install skipped" ;;
    esac

Except automated package installation, you may also need to download and install
software manually. If you want to make these steps skippable, here is an
example.

Example 3::

    if [ "${SKIP_INSTALL}" = "true" ] || [ "${SKIP_INSTALL}" = "True" ]; then
        dist_name
        case "${dist}" in
            debian|ubuntu) install_deps "${pkgs}" ;;
            fedora|centos) install_deps "${pkgs}" ;;
            unknown) warn_msg "Unsupported distro: package install skipped" ;;
        esac

        # manually install steps.
        git clone "${repo}"
        cd "${dir}"
        ./configure && make install
    fi

Hopefully, the above 3 examples cover most of the user cases. When
writing test cases, in general:

    * Define 'SKIP_INSTALL' variable with 'false' as default.
    * Add parameter '-s <True|False>', so that user can modify 'SKIP_INSTALL'.
    * Try to use the above functions, and give unknown distributions more care.

3. Saving output
~~~~~~~~~~~~~~~~~

'test-case-name/output' directory is recommended to save test log and result
files.

4. Parsing result
~~~~~~~~~~~~~~~~~

Saving parsed result in the same format is important for post process such as
sending to LAVA. The following result format should be followed.

    test-caes-id pass/fail/skip
    test-case-id pass/fail/skip measurement
    test-case-id pass/fail/skip measurement units

'output/result.txt' file is recommended to save result.

We encourage test writers to use the functions defined in 'sh-test-lib' to format
test result.

Print "test-case pass/fail" by checking exit code::

    check_return "${test_case_id}"

Add a metric for performance test::

    add_metic "${test-case-id}" "pass/fail/skip" "${measurement}" "${units}"


5. Running in LAVA
~~~~~~~~~~~~~~~~~~

LAVA is the foundation of test automation in Linaro. It is able to handle image
deployment and boot, and provides a test shell for test run. To run a test case
in LAVA, a definition file in YAML format is required.

Bear in mind, do all the LAVA-specific steps in test definition file, and do not
use any LAVA-specific steps in test script, otherwise you may lock yourself out
of your own test case when LAVA isn't available or the board you want to test
wasn't deployed in LAVA.

Test script should handle dependencies installation, test execution, result
parsing and other work in a self-contained way, and produce result.txt file with
a format that can be easily parsed and sent to LAVA. This is a more robust way.
Test case works with/without LAVA and can be tested locally.

A general test definition file should contain the below keywords and steps::

    metadata:
    # Define parameters required by test case with default values.
    params:
      SKIP_INSTALL: False
    run:
      # A typical test run in LAVA requires the below steps.
      steps:
        # Enter the directory of the test case.
        - cd ./automated/linux/smoke/
        # Run the test.
        - ./smoke.sh -s "${SKIP_INSTALL}"
        # Send the results in result.txt to LAVA.
        - ../../utils/send-to-lava.sh ./output/result.txt

Android specific
----------------

The above test writing guidelines also apply to Android test cases. The major
difference is that we run all Android test cases through adb shell. Compare with
local run, adb and adb shell enable us to do more. And this model is well
supported by LAVA V2 LXC protocol.

A typical Android test case can be written with the following steps::

    # Check adb connect with initialize_adb funtion
    initialize_adb
    # Install binaries and scripts
    detect_abi
    install "../../bin/${abi}/busybox"
    install "./device-script.sh"
    # Run test script through adb shell.
    adb -s "${SN}" shell device-script.sh
    # Pull output from device for parsing.
    pull_output "${DEVICE_OUTPUT}" "${HOST_OUTPUT}"

Test Contribution Checklist
===========================

* When applicable, check test cases with the following tools with line length
  rule relaxed.

    - checkbashisms - check for bashisms in /bin/sh scripts.
    - shellcheck - Shell script analysis tool.
    - pep8 - check Python code against the style conventions in PEP 8.
    - pyflakes - simple Python 2 source checker
    - pylint - code analysis for Python

* Run test cases on local system without LAVA.
* Optionally, run test cases in LAVA and provide job example.