blob: b23badd8a93c1df1d7a4cf6fac1cb35cc289201d [file] [log] [blame]
Chase Qi840edf22016-09-02 16:24:58 +08001=======================
2Test Writing Guidelines
3=======================
4
Nicolas Dechesnec4c736a2017-01-24 21:15:11 +01005This document describes guidelines and is intended for anybody who wants to write
Chase Qi840edf22016-09-02 16:24:58 +08006or modify a test case. It's not a definitive guide and it's not, by any means, a
7substitute for common sense.
8
9General Rules
10=============
11
121. Simplicity
13-------------
14
Nicolas Dechesnec4c736a2017-01-24 21:15:11 +010015It's worth keeping test cases as simple as possible.
Chase Qi840edf22016-09-02 16:24:58 +080016
172. Code duplication
18-------------------
19
20Whenever you are about to copy a large part of the code from one test case to
21another, think if it is possible to move it to a library to reduce code
22duplication and the cost of maintenance.
23
243. Coding style
25---------------
26
27Use common sense and BE CONSISTENT.
28
29If you are editing code, take a few minutes to look at the code around you and
30determine its style.
31
32The point of having style guidelines is to have a common vocabulary of coding so
33people can concentrate on what you are saying, rather than on how you are saying
34it.
35
363.1 Shell coding style
37~~~~~~~~~~~~~~~~~~~~~~
38When writing test cases in shell write in *portable shell* only.
39
40You can either try to run the test cases on Debian which has '/bin/sh' pointing
41to 'dash' by default or install 'dash' on your favorite distribution and use
42it to run the tests.
43
44Ref: `Shell Style Guide <https://google.github.io/styleguide/shell.xml>`_
45
463.2 Python coding style
47~~~~~~~~~~~~~~~~~~~~~~~
48Please follow PEP 8 style guide whenever possible.
49
50Ref: `PEP 8 <https://www.python.org/dev/peps/pep-0008/>`_
51Easy-to-read version of PEP 8 available at `pep8.org <http://pep8.org>`_
52
534. Commenting code
54------------------
55
56Use useful comments in your program to explain:
57
Chase Qi6d96a9f2019-01-23 17:17:48 +080058- assumptions
59- important decisions
60- important details
61- problems you're trying to solve
62- problems you're trying to overcome in your program, etc.
Chase Qi840edf22016-09-02 16:24:58 +080063
64Code tells you how, comments should tell you why.
65
665. License
67----------
68Code contributed to this repository should be licensed under GPLv2+ (GNU GPL
69version 2 or any later version).
70
71Writing a test case
72===================
73
74Linux
75------
76
771. Structure
78~~~~~~~~~~~~
79
Nicolas Dechesnec4c736a2017-01-24 21:15:11 +010080Tests are generally placed under 'linux/' directory. Everything that relates to
Chase Qi840edf22016-09-02 16:24:58 +080081the test goes under the same folder named with test case name.
82
83Define 'linux/test-case-name/output' folder in test case to save test output and
84result. Using a dedicated folder is helpful to distinguish between test script
85and test output.
86
Nicolas Dechesnec4c736a2017-01-24 21:15:11 +0100872. Installing dependencies
88~~~~~~~~~~~~~~~~~~~~~~~~~~
Chase Qi840edf22016-09-02 16:24:58 +080089
Nicolas Dechesnec4c736a2017-01-24 21:15:11 +010090The same test case should work on Debian/Ubuntu, Fedora/CentOS and OE based
91distributions whenever possible. This can be achieved with install_deps()
Chase Qic246bb42017-01-13 16:12:35 +080092function. The following is a simple example. "${SKIP_INSTALL}" should be set to
Nicolas Dechesnec4c736a2017-01-24 21:15:11 +010093'true' on distributions that do not supported install_deps(). In the unsupported
94case, if "${SKIP_INSTALL}" is 'true', install_deps() still will skip package
Chase Qic246bb42017-01-13 16:12:35 +080095installation.
Chase Qi840edf22016-09-02 16:24:58 +080096
Chase Qic246bb42017-01-13 16:12:35 +080097Example 1::
Chase Qi840edf22016-09-02 16:24:58 +080098
Chase Qic246bb42017-01-13 16:12:35 +080099 install_deps "${pkgs}" "${SKIP_INSTALL}"
Chase Qi840edf22016-09-02 16:24:58 +0800100
Chase Qic246bb42017-01-13 16:12:35 +0800101Package name may vary by distribution. In this case, you will need to handle
Nicolas Dechesnec4c736a2017-01-24 21:15:11 +0100102package installation with separate lines. dist_name() function is designed to
Chase Qic246bb42017-01-13 16:12:35 +0800103detect the distribution ID at running time so that you can define package name
104by distribution. Refer to the following example.
Chase Qi840edf22016-09-02 16:24:58 +0800105
Chase Qic246bb42017-01-13 16:12:35 +0800106Example 2::
Chase Qi840edf22016-09-02 16:24:58 +0800107
108 dist_name
109 case "${dist}" in
Nicolas Dechesneb7e38762017-01-25 12:07:08 +0100110 debian|ubuntu) install_deps "lsb-release" "${SKIP_INSTALL}" ;;
111 fedora|centos) install_deps "redhat-lsb-core" "${SKIP_INSTALL}" ;;
Chase Qi475120c2017-02-06 12:06:01 +0800112 *) warn_msg "Unsupported distro: ${dist}! Package installation skipped." ;;
Chase Qi840edf22016-09-02 16:24:58 +0800113 esac
Chase Qic246bb42017-01-13 16:12:35 +0800114
115Except automated package installation, you may also need to download and install
116software manually. If you want to make these steps skippable, here is an
117example.
118
119Example 3::
120
121 if [ "${SKIP_INSTALL}" = "true" ] || [ "${SKIP_INSTALL}" = "True" ]; then
122 dist_name
123 case "${dist}" in
Nicolas Dechesneb7e38762017-01-25 12:07:08 +0100124 debian|ubuntu) install_deps "${pkgs}" ;;
125 fedora|centos) install_deps "${pkgs}" ;;
Chase Qi475120c2017-02-06 12:06:01 +0800126 *) warn_msg "Unsupported distro: ${dist}! Package installation skipped." ;;
Chase Qic246bb42017-01-13 16:12:35 +0800127 esac
128
129 # manually install steps.
130 git clone "${repo}"
131 cd "${dir}"
Nicolas Dechesnec4c736a2017-01-24 21:15:11 +0100132 ./configure && make install
Chase Qic246bb42017-01-13 16:12:35 +0800133 fi
134
Nicolas Dechesnec4c736a2017-01-24 21:15:11 +0100135Hopefully, the above 3 examples cover most of the user cases. When
136writing test cases, in general:
Chase Qic246bb42017-01-13 16:12:35 +0800137
Chase Qi6d96a9f2019-01-23 17:17:48 +0800138- Define 'SKIP_INSTALL' variable with 'false' as default.
139- Add parameter '-s <True|False>', so that user can modify 'SKIP_INSTALL'.
140- Try to use the above functions, and give unknown distributions more care.
Chase Qi840edf22016-09-02 16:24:58 +0800141
1423. Saving output
143~~~~~~~~~~~~~~~~~
144
145'test-case-name/output' directory is recommended to save test log and result
146files.
147
1484. Parsing result
149~~~~~~~~~~~~~~~~~
150
151Saving parsed result in the same format is important for post process such as
Chase Qi6d96a9f2019-01-23 17:17:48 +0800152sending to LAVA. The following result format should be followed::
Chase Qi840edf22016-09-02 16:24:58 +0800153
Chase Qifd136452019-03-04 11:06:45 +0800154 test-case-id pass/fail/skip
Nicolas Dechesnec4c736a2017-01-24 21:15:11 +0100155 test-case-id pass/fail/skip measurement
Chase Qi840edf22016-09-02 16:24:58 +0800156 test-case-id pass/fail/skip measurement units
157
158'output/result.txt' file is recommended to save result.
159
Nicolas Dechesnec4c736a2017-01-24 21:15:11 +0100160We encourage test writers to use the functions defined in 'sh-test-lib' to format
Chase Qi840edf22016-09-02 16:24:58 +0800161test result.
162
163Print "test-case pass/fail" by checking exit code::
164
165 check_return "${test_case_id}"
166
167Add a metric for performance test::
168
Nicolas Dechesnec4c736a2017-01-24 21:15:11 +0100169 add_metic "${test-case-id}" "pass/fail/skip" "${measurement}" "${units}"
Chase Qi840edf22016-09-02 16:24:58 +0800170
171
1725. Running in LAVA
173~~~~~~~~~~~~~~~~~~
174
175LAVA is the foundation of test automation in Linaro. It is able to handle image
176deployment and boot, and provides a test shell for test run. To run a test case
177in LAVA, a definition file in YAML format is required.
178
179Bear in mind, do all the LAVA-specific steps in test definition file, and do not
180use any LAVA-specific steps in test script, otherwise you may lock yourself out
181of your own test case when LAVA isn't available or the board you want to test
182wasn't deployed in LAVA.
183
184Test script should handle dependencies installation, test execution, result
185parsing and other work in a self-contained way, and produce result.txt file with
186a format that can be easily parsed and sent to LAVA. This is a more robust way.
187Test case works with/without LAVA and can be tested locally.
188
189A general test definition file should contain the below keywords and steps::
190
191 metadata:
192 # Define parameters required by test case with default values.
193 params:
194 SKIP_INSTALL: False
195 run:
196 # A typical test run in LAVA requires the below steps.
197 steps:
198 # Enter the directory of the test case.
199 - cd ./automated/linux/smoke/
200 # Run the test.
201 - ./smoke.sh -s "${SKIP_INSTALL}"
202 # Send the results in result.txt to LAVA.
203 - ../../utils/send-to-lava.sh ./output/result.txt
204
205Android specific
206----------------
207
208The above test writing guidelines also apply to Android test cases. The major
209difference is that we run all Android test cases through adb shell. Compare with
210local run, adb and adb shell enable us to do more. And this model is well
211supported by LAVA V2 LXC protocol.
212
213A typical Android test case can be written with the following steps::
214
215 # Check adb connect with initialize_adb funtion
216 initialize_adb
217 # Install binaries and scripts
218 detect_abi
219 install "../../bin/${abi}/busybox"
220 install "./device-script.sh"
221 # Run test script through adb shell.
222 adb -s "${SN}" shell device-script.sh
223 # Pull output from device for parsing.
224 pull_output "${DEVICE_OUTPUT}" "${HOST_OUTPUT}"
225
Milosz Wasilewski05b2d382017-04-18 16:36:41 +0100226
2276. Using test-runner
228~~~~~~~~~~~~~~~~~~~~
229
230Using test-runner to run tests locally
231--------------------------------------
232
233The tests can be run directly on the board, assuming you have installed basic
234tools such as git, gcc, ... `test-runner` is written in Python and requires
235`pexpect` and `yaml` modules to be installed as well. To run tests directly
236on the board, get a prompt and run::
237
238 git clone http://git.linaro.org/qa/test-definitions.git
239 cd test-definitions
240 source automated/bin/setenv.sh
241 test-runner -p plans/rpb_ee/rpb_ee_functional.yaml
242
243By default the test output are stored in `$HOME/output/`, and the output folder
244can be configured with `-o` argument.
245
246Using test-runner to run tests from host PC
247-------------------------------------------
248
249It is also possible to run tests from a host PC if the board is available on
250the network. In that case `test-runner` will connect to the board over SSH, and
251you need to setup the board so that the host PC can connect to the board over
252SSH without any prompt (password less connection). To run from the host, run
253the following commands from the host command prompt::
254
255 git clone http://git.linaro.org/qa/test-definitions.git
256 cd test-definitions
257 source automated/bin/setenv.sh
258 test-runner -g root@ip -p plans/rpb_ee/rpb_ee_functional.yaml
259
260Where `root@ip` is the credential to connect to the board over SSH.
261
262By default the test output are stored in `$HOME/output/root@ip`, and the output
263folder can be configured with `-o` argument.
264
265Running individual tests
266------------------------
267
268Instead of running a test plan with `-p` argument, it is possible to run a single
269test only using `-d` argument.
270
271Test output
272-----------
273
274At the end of the test run, the following artefact are available in the output
275folder:
276
Chase Qi6d96a9f2019-01-23 17:17:48 +0800277- `result.csv` and `result.json` which contain summary of test results
278 (including test name, test case ID, test results such as pass, fail, skip,
279 test measurement, if any, with the associated measurement unit, and the test
280 argument used
281- For each test executed, there is a folder which contains the console output
282 of the test run, `stdout.log` as well as all test scripts/data
Milosz Wasilewski05b2d382017-04-18 16:36:41 +0100283
Chase Qi840edf22016-09-02 16:24:58 +0800284Test Contribution Checklist
285===========================
286
Chase Qi6d96a9f2019-01-23 17:17:48 +0800287- When applicable, check test cases with the following tools with line length
Chase Qi840edf22016-09-02 16:24:58 +0800288 rule relaxed.
289
Chase Qi6d96a9f2019-01-23 17:17:48 +0800290 - shellcheck: Shell script analysis tool.
291 - pycodestyle: check Python code against the style conventions in PEP 8.
292 - php: check syntax with 'php -l file'.
Chase Qi840edf22016-09-02 16:24:58 +0800293
Chase Qi6d96a9f2019-01-23 17:17:48 +0800294- Run test cases on local system without LAVA.
295- Optionally, run test cases in LAVA and provide job example.