1. What is data-driven
What is parameterization? What is data-driven? There are often people who don’t understand their relationship, so let’s take a look at two of the most common scenarios in the test:
Login: Different user names, passwords, and combinations need to be tested in login scenarios. Multiple use cases may be generated in normal combinations
Search: different search conditions produce different search results, search is also a common test item, a single search parameter or a combination of multiple search parameters; Multiple use cases are also generated.
The above two scenarios have one thing in common, that is, the execution steps of the test remain the same, but only the input test data changes, which leads to two concepts — parameterization and data-driven
Parameterization: There are many methods when we write automatic use cases. Generally, we will pass the data to the method through parameters, rather than directly write “dead” in the method. Therefore, data transfer between methods is carried out through parameterization. For example, our login account password is set in the parameter, and the parameter is passed to the method.
public MainPage login(String username, String password) { sendKeys(inputUsername,username); sendKeys(inputPassword,password); click(loginBtn); returnnew MainPage(); }Copy the code
Data-driven: Change the source of data in parameterization to read from outside. Parameters have a place to store data and remove data during use case execution. This data can be stored in an array we define, a HashMap, or it can be read from an external file (Excel, CSV, XML, YAML, etc.).
For example, in the search case above, we can put the search criteria in an external file, and each time we execute the search case, we can fetch the data from the file and perform different search tests based on the data obtained.
-- Laundry detergent -- Hat -- glovesCopy the code
To sum up:
Data-driven is a design idea of automatic testing framework, and parameterization is a means to realize data-driven. We use parameterization to complete data-driven, thus separating data from script, increasing maintainability of framework and reuse of script.
2. Why data-driven
2.1 Test Data
During the execution of testing work, there are many processes that need to change dynamically. If every change needs to be coded and deployed, the whole execution process will be lengthened.
For business test engineers, there is a certain threshold to maintain automation code, and they need to be familiar with the structure of programming language and testing framework.
After the data drive is defined, changing data can be maintained in the configuration file, which is convenient (no need to find the corresponding code to modify the deployment) and reduces the maintenance threshold (business tests only need to modify data in the configuration file).
2.2 Test Procedure
Similar to the data drive of test data, it is mainly convenient for business test and maintenance, reducing the maintenance threshold and the risk of error in code modification and deployment. By modifying the configuration file, the entire business behavior and abstractions remain unchanged, and of course, using PO in UI automation “tastes better”.
2.3 Dynamically generating test steps
It is difficult to record test steps manually and generate code directly. You can generate a configuration file for the steps and let the code read the configuration file to complete automatic playback. (I have only known about this for the time being, and it is possible to achieve it in theory.)
3. Where is data driven
3.1 Where not to be data-driven
Don’t do a lot of data-driven work in test cases: use cases are very clear about business execution scenarios through PO calls, and business is the core of the use case; Once a large number of data drivers are used in use cases, such as calling various data files such as YAML and CSV, the readability of use cases will become worse and the maintenance complexity will become higher.
3.2 Where can data be driven
1. Test data driven
2. Data-driven test steps
- locator
- Behavior of flow
3. Data-driven assertion
4. How to be data-driven
4.1 Selection of data format
We want to store the data in files, different files have different data formats, so what choice?
- Comparison of files in different data formats
From the above comparison results, Json and YAML support and write data structures well. However, YAML is written more succinct and annotated, so the most recommended use (as you can guess from the table location) is… YAML! At bit C
So what exactly is YAML and how do you use it
4.2 Using YAML Files
Yaml syntax
- Case sensitivity
- Use indentation to indicate hierarchy
- The Tab key is not allowed for indentation. Only Spaces are allowed.
- The number of Spaces indented does not matter, as long as elements of the same rank are aligned to the left
- # comment
Three data structures supported by YAML
- Scalars: Single, non-separable values, such as numbers, strings, booleans, and so on
- Object: a collection of key-value pairs, also known as mapping/hashes/dictionary
Person: {name: Allen, age: 25}Copy the code
- 1. An ordered set of values, also called a sequence/list.
# is represented as an array of values starting with - - A- B- C# nested subarrays, represented by A space indentation - - A- aa- - B- bbCopy the code
- Objects and arrays can be used together to form composite structures
languages: - Ruby - Perl - Python websites: YAML: yaml.org Ruby: ruby-lang.org Python: python.org Perl: use.perl.orgCopy the code
4.3 Reading Data – Jackson
Now that you have a place to store your data, you need to read it, and here’s another helper, the Java Jackson library
Jackson is a Java library, most commonly used in jackson-databind and jackson-dataformats-text, which handle json and yaml dataformats, respectively. Jackson maps data from files to objects in Java.
To associate a file’s data by type and create an instance of a class, or write an object to a file.
4.3.1 Jackson – databind
Let’s take a look at jackson-Databind on a JSON file
Adding Maven dependencies
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> The < version > 2.9.9.3 < / version > < / dependency >Copy the code
- To write the json file
1) Create a class containing variables name, age
public class TestFileSource { public String name; public int age; }Copy the code
2) Create unit test, create ObjectMapper object, call writeValue to write to JSON file
@Testvoid writeJson() throws IOException { ObjectMapper mapper = new ObjectMapper(); TestFileSource testFileSource = new TestFileSource(); mapper.writeValue(new File(".. \\demo.json"),testFileSource); }Copy the code
3) Get the result of the demo.json file, which shows that variables from the TestFileSource class have been written to the JSON file
{"name":null,"age": 0}Copy the code
- Read the json files
1) Create unit test, create ObjectMapper object, call readValue method to read data from JSON file
@Testvoid readJson() throws IOException { ObjectMapper mapper = new ObjectMapper(); TestFileSource testFileSource = mapper.readValue(TestFileSource.class.getResourceAsStream("/demo.json"), TestFileSource.class); System.out.println(testFileSource); System.out.println(testFileSource.age); }Copy the code
2) Read the results
ApiDemos.testcase.TestFileSource@4562e04d 0Copy the code
- Output beautiful JSON format
1) create a unit test, create ObjectMapper object, call writerWithDefaultPrettyPrinter () writeValueAsString method can be carried out on the specified object json data format of the output
@Testvoid prettyPrintJson() throws JsonProcessingException { ObjectMapper mapper = new ObjectMapper(); // pretty printString json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(new TestFileSource()); System.out.println(json); }Copy the code
2) Print the results
{ "name" : null, "age" : 0}Copy the code
Reference link Jackson-Databind GitHub address:
https://github.com/FasterXML/jackson-databind
4.3.2 Jackson – dataformats – text
Jackson-dataformats -text is a library that operates on YAML, CSV, Properties and XML files. It’s the most common one, but we’ll focus on what it does to YAML files
- Adding Maven dependencies
<dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-yaml</artifactId> The < version > 2.9.8 < / version > < / dependency >Copy the code
- Read YAML files
To read a YAML file, add new YAMLFactory() to the new ObjectMapper object. This successfully switches to the YAML operation state, and the readValue method is used to read the data from the YAML file
1) Create YAML files
name: allenage: 11Copy the code
2) Create ObjectMapper and set new YAMLFactory()
@Testvoid readYaml() throws IOException { ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); TestFileSource testFileSource = mapper.readValue(TestFileSource.class.getResourceAsStream("/demo2.yaml"), TestFileSource.class); System.out.println(testFileSource); System.out.println(testFileSource.age); }Copy the code
Print the result
ApiDemos.testcase.TestFileSource@ba2f4ec11Copy the code
As you can see in the readValue method, the first argument is the file address, and the second argument is the essence! We can give an object type, or a two-dimensional array, etc., to generate a mapping relationship, the file data and our object binding, convenient data reading.
In the example above we call the age variable from the instantiation object of TestFileSource.
- Output nice YAML format
1) Create a class and its member variables, including scalar, array, and hash
public class TestFileSource { public String name = "tester"; public int age = 2; Public Object [] [] arr = {{1, 2, 3}, {"a"."b"."c"}}; public HashMap<String,Object> map = new HashMap<String, Object>(){ { put("name"."tester"); put("sex"."Male"); } };}Copy the code
2) Create unit test, create ObjectMapper object, add new YAMLFactory() parameter, Call writerWithDefaultPrettyPrinter () writeValueAsString method can be carried out on the specified object yaml data format of the output
@Testvoid prettyPrintYaml() throws JsonProcessingException { ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); // pretty printString json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(new TestFileSource()); System.out.println(json); }Copy the code
3) Print the results
---name: "tester"age: 2arr:- - 1 - 2 - 3- - "a" - "b" - "c"map: sex: "Male" name: "tester"Copy the code
(Article from Hogwarts Testing Institute)
Welfare benefits:
Front-line Internet famous enterprises test development position internal promotion channel
Test development internal communication circle, expand your test network
For free: Interface testing + Performance testing + Automated testing + Test development + Test cases + resume template + test documentation