blob: eb422f6cf2bdd5e7256de193349a8602b5d996b4 [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
58 * 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.
63
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}" ;;
112 unknown) warn_msg "Unsupported distro: package install 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}" ;;
126 unknown) warn_msg "Unsupported distro: package install 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
138 * 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
152sending to LAVA. The following result format should be followed.
153
154 test-caes-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
226Test Contribution Checklist
227===========================
228
229* When applicable, check test cases with the following tools with line length
230 rule relaxed.
231
232 - checkbashisms - check for bashisms in /bin/sh scripts.
233 - shellcheck - Shell script analysis tool.
234 - pep8 - check Python code against the style conventions in PEP 8.
235 - pyflakes - simple Python 2 source checker
236 - pylint - code analysis for Python
237
238* Run test cases on local system without LAVA.
239* Optionally, run test cases in LAVA and provide job example.