Merge "Fully cover the decorator"
[functest.git] / docs / com / pres / framework / framework.md
1 # Functest Framework
2
3 created by [Cédric Ollivier](mailto:cedric.ollivier@orange.com)
4
5 2017/05/06
6
7 Note:
8
9 - Functest integrates lots of heterogeneous testcases:
10     - python vs bash
11     - internal vs external
12 - it aims to benefit from object programming
13     - to define common operations
14     - to avoid conditional instructions regarding the testcases
15     - to avoid duplicating code
16     - to ease the integration of third-party testcases (written in Bash or Python)
17
18
19
20 ## Quick overview
21
22
23 ### Functest function calls
24
25 - **CI** calls *run_tests.py* (please see [jenkins jobs](https://gerrit.opnfv.org/gerrit/gitweb?p=releng.git;a=tree;f=jjb/functest))
26 - *run_tests.py* parses *functest/ci/testcases.yaml* to:
27     - check which testcase(s) must be run
28     - execute the common operations on every testcase (run, push its results to db...)
29 <!-- .element: class="fragment highlight-red"-->
30     - return the right status code to **CI**
31
32
33 ### Our target
34
35 - limit run_tests.py instructions by defining:
36     - the basic testcase attributes
37     - all common operations
38     - the status codes expected
39 - avoid duplicating codes between testcases
40 - ease the development of third-party testcases (aka features)
41
42
43
44 ## class TestCase
45
46 base model for single test case
47
48
49 ### instance attributes
50
51 - project_name (default: 'functest')
52 - case_name
53 - criteria
54 - result
55 - start_time
56 - stop_time
57 - details
58
59
60 ### methods
61
62 | Method            | Purpose                                    |
63 |-------------------|--------------------------------------------|
64 | run(**kwargs)     | run the test case                          |
65 | is_successful()   | interpret the results of the test case     |
66 | get_duration()    | return the duration of the test case       |
67 | push_to_db()      | push the results of the test case to the DB|
68
69
70 ### run(**kwargs)
71
72 - the subclasses must override the default implementation which is false on purpose
73 - the new implementation must set the following attributes to push the results to DB:
74     - result
75     - start_time
76     - stop_time
77
78
79 ### class attributes
80
81 | Status code        | Returned when       |
82 |--------------------|---------------------|
83 | EX_OK              | everything is OK    |
84 | EX_RUN_ERROR       | run() failed        |
85 | EX_TESTCASE_FAILED | results are false   |
86 | EX_PUSH_TO_DB_ERROR| push_to_db() failed |
87
88
89 ### run_tests.py
90
91 ```python
92 module = importlib.import_module(run_dict['module'])
93 cls = getattr(module, run_dict['class'])
94 test_dict = ft_utils.get_dict_by_test(test_name)
95 test_case = cls(**test_dict)
96 try:
97     kwargs = run_dict['args']
98     result = test_case.run(**kwargs)
99 except KeyError:
100     result = test_case.run()
101 if result == testcase.TestCase.EX_OK:
102     if GlobalVariables.REPORT_FLAG:
103         test_case.push_to_db()
104     result = test_case.is_successful()
105 ```
106
107
108
109 ## Your first test case
110
111
112 ### first.py
113
114 ```python
115 #!/usr/bin/env python
116
117 import time
118
119 from functest.core import testcase
120
121 class Test(testcase.TestCase):
122
123     def run(self, **kwargs):
124         self.start_time = time.time()
125         print "Hello World"
126         self.result = 100
127         self.stop_time = time.time()
128         return testcase.TestCase.EX_OK
129 ```
130
131
132 ### functest/ci/testcases.yaml
133
134 ```yaml
135 case_name: first
136 project_name: functest
137 criteria: 100
138 blocking: true
139 clean_flag: false
140 description: ''
141 dependencies:
142     installer: ''
143     scenario: ''
144 run:
145     module: 'first'
146     class: 'Test'
147 ```
148
149
150
151 ## class Feature
152 bases: TestCase
153
154 base model for single feature
155
156
157 ### methods
158
159 | Method            | Purpose                   |
160 |-------------------|---------------------------|
161 | run(**kwargs)     | run the feature           |
162 | execute(**kwargs) | execute the Python method |
163
164
165 ### run(**kwargs)
166
167 - allows executing any Python method by calling execute()
168 - sets the following attributes required to push the results to DB:
169     - result
170     - start_time
171     - stop_time
172 - doesn't fulfill details when pushing the results to the DB.
173
174
175 ### execute(**kwargs)
176
177 - the subclasses must override the default implementation which is false on purpose
178 - the new implementation must return 0 if success or anything else if failure.
179
180
181
182 ## Your second test case
183
184
185 ### second.py
186
187 ```python
188 #!/usr/bin/env python
189
190 from functest.core import feature
191
192 class Test(feature.Feature):
193
194     def execute(self, **kwargs):
195         print "Hello World"
196         return 0
197 ```
198
199
200 ### functest/ci/testcases.yaml
201
202 ```yaml
203 case_name: second
204 project_name: functest
205 criteria: 100
206 blocking: true
207 clean_flag: false
208 description: ''
209 dependencies:
210     installer: ''
211     scenario: ''
212 run:
213     module: 'second'
214     class: 'Test'
215 ```
216
217
218
219 ## class BashFeature
220 bases: Feature
221
222 class designed to run any bash command
223
224
225 ### execute(**kwargs)
226
227 execute the cmd passed as arg.
228
229
230
231 ## Your third test case
232
233
234 ### functest/ci/testcases.yaml
235
236 ```
237 case_name: third
238 project_name: functest
239 criteria: 100
240 blocking: true
241 clean_flag: false
242 description: ''
243 dependencies:
244     installer: ''
245     scenario: ''
246 run:
247     module: 'functest.core.feature'
248     class: 'BashFeature'
249     args:
250         cmd: 'echo Hello World; exit 0'
251 ```
252
253
254
255 ## Euphrates
256
257
258 ### Next actions
259
260 - __to finish VNF abstraction (coverage + pylint)__
261 - to publish doc API
262 - to manage criteria as written in testcases.yaml
263
264 Please see [Functest Euphrates page](https://wiki.opnfv.org/display/functest/Functest+Euphrates+page) for more details
265
266
267
268 ## Thank You!