Switching multiple data Sources in Java Automation testing

Source: Internet
Author: User
Tags readfile

When doing automated testing, data-driven is a very important concept, when the data and script separation, the face of the vast number of data, management data has become a big problem, and the data source may face multiple, as in the development process, sometimes to connect MySQL, and sometimes connected to SQL Server, How do I switch quickly? In the following example, we'll start with a data source and step through the demo:

I. Basic data-driven writing with external files

1.1 When we are doing data-driven, we store the data in the Java properties file: Data.properties

username=testpassword=123456

1.2 Parsing properties File

public class Propertieshandler {private static Properties Loadpropertiesfile ( String filePath) {Properties P = new Properties (); InputStream in = null;try {in = new FileInputStream (new File (FilePath));p . Load (in); catch (FileNotFoundException e) {e.printstacktrace ();} catch (IOException e) {e.printstacktrace ();} Finally{try {if (in! = null) {In.close ();}} catch (IOException e) {e.printstacktrace ()}} return p;} /** * Convert property to MAP * @param key * @return */@SuppressWarnings ({"Rawtypes", "Unchecked"}) public static map<string, String> Getpropertydata (String filePath) {try{return new hashmap<string, string> (MAP) Propertiesha        Ndler.loadpropertiesfile (FilePath));        }catch (Exception e) {e.printstacktrace ();    } return new hashmap<string, string> (); }public static void Main (string[] args) {System.out.println (Propertieshandler.getpropertydata ("File/data.properties "));}}

1.3 Write a Testbase class, which is used to store testng Dataprovider

public class Testbase {@DataProviderpublic object[][] Dataprovider () {return this.gettestdata ();} Private object[][] Gettestdata () {Propertiesdata testData = new Propertiesdata (); list<map<string, string>> listData = Testdata.gettestmethoddata (); object[][] Object = new object[ Listdata.size ()][];for (int i = 0; i < listdata.size (); i++) {Object[i] = new Object[]{listdata.get (i)};} return object;}}

As you can see, as long as I have a class that can provide a two-dimensional array of data types: list<map<string, string>> data objects that can be converted to object[][], it can be provided to the test method to run.

1.4 In 1.3 There is a propertiesdata class that now implements this class

public class Propertiesdata {public list<map<string, string>> Gettestmethoddata () {list<map<string, string>> list = new arraylist<map<string, string>> (); List.add (Propertieshandler.getpropertydata (" File/data.properties ")); return list;}}

More than 1.5 in the data parsing class, there is data load class, there is the basic class of data provided, so we combine the test method, the three basic classes to join together, formed an external file to do a complete example of the data source:

public class Testdemo extends testbase{@Test (dataprovider= "Dataprovider") public void Testdemo (map<string, String > param) {System.out.println (Param.get ("username")); System.out.println (Param.get ("password"));}}

More than 1.6 of the running result output is:

Two. Implementation of the TXT file for the property file

2.1 If there are multiple data sources, I want to use TXT to store the data, TXT contains a JSON string: data.txt

{"username": "Test", "Password": "123456"}

2.2 read out this TXT file

public class FileUtils {public static string ReadFile (String fileName) {InputStream is = null; StringBuffer sb = new StringBuffer (); try {is = new FileInputStream (fileName); byte[] Bytebuffer = new byte[is.available ()]; int read = 0;while ((read = Is.read (bytebuffer))! =-1) {Sb.append (new String (Bytebuffer, 0, read));}} catch (FileNotFoundException e) {e.printstacktrace ();} catch (IOException e) {e.printstacktrace ();} Finally{try {if (is!=null) {is.close ();}} catch (IOException e) {e.printstacktrace ();}} return sb.tostring ();} public static void Main (string[] args) {System.out.println (Fileutils.readfile ("File/data.txt"));}}

2.3 Parse the Read JSON string (a jar package is needed here, Gson.jar)

public class Txtdata {public list<map<string, string>> Gettestmethoddata () {list<map<string, String >> list = new arraylist<map<string, string>> (); String data = Fileutils.readfile ("File/data.txt"); Gson Gson = new Gson (); map<string, string> dataMap = Gson.fromjson (data, New typetoken<map<string, string>> () {}.getType ()) ; List.add (dataMap); return list;}}

2.4 The Txtdata class to use, will be Testbase class in the use of Propertiesdata class place replaced by Txtdata class can be

Private object[][] Gettestdata () {txtdata testData = new Txtdata (); list<map<string, string>> listData = Testdata.gettestmethoddata (); object[][] Object = new object[ Listdata.size ()][];for (int i = 0; i < listdata.size (); i++) {Object[i] = new Object[]{listdata.get (i)};} return object;}

2.5 When you run the Testdemo test class, the results are identical to the results that were previously shown with the Propertiesdata class.

Three. Using the interface to achieve

3.1 The above two data sources, in the data source content to load and load out the data type is: List<map<string, string>>, only need to testbase class of the data source load class to replace one, so that , we can use the Java interface to refactor our code, first of all, of course we have to have a interface

Public interface Datainterface {public list<map<string, string>> gettestmethoddata ();}

3.2 Our Propertiesdata class and the Txtdata class will certainly implement this interface.

public class Propertiesdata implements Datainterface{public list<map<string, string>> gettestmethoddata () {list<map<string, string>> List = new arraylist<map<string, string>> (); List.add ( Propertieshandler.getpropertydata ("file/data.properties")); return list;}}
public class Txtdata implements Datainterface{public list<map<string, string>> gettestmethoddata () {List <map<string, string>> list = new arraylist<map<string, string>> (); String data = Fileutils.readfile ("File/data.txt"); Gson Gson = new Gson (); map<string, string> dataMap = Gson.fromjson (data, New typetoken<map<string, string>> () {}.getType ()) ; List.add (dataMap); return list;}}

3.3 And then there's a change in Testbase, that is, the class object that generated the data load is going to change, and we're adding a new method to the Testbase (this is a new way to produce the class object)

Private Datainterface getdatainstance (String key) {Datainterface data = null;try {data = (Datainterface) class.forname ( Key). Newinstance ();} catch (Instantiationexception | illegalaccessexception | ClassNotFoundException e) {e.printstacktrace ();} return data;}

The Gettestdata () method in the 3.4 Testbase class is going to change a little bit again.

Private object[][] Gettestdata () {Datainterface testData = this.getdatainstance ("Com.test.testdata.PropertiesData"); list<map<string, string>> listData = Testdata.gettestmethoddata (); object[][] Object = new object[ Listdata.size ()][];for (int i = 0; i < listdata.size (); i++) {Object[i] = new Object[]{listdata.get (i)};} return object;}
Private object[][] Gettestdata () {Datainterface testData = this.getdatainstance ("Com.test.testdata.TxtData"); list<map<string, string>> listData = Testdata.gettestmethoddata (); object[][] Object = new object[ Listdata.size ()][];for (int i = 0; i < listdata.size (); i++) {Object[i] = new Object[]{listdata.get (i)};} return object;}

3.5 Run Testdemo again to see that the results are still the same. So, just change the path to the data-loading class.

Four. Configure the path to the data-loading class

4.1 This time, we can think of the data load class path is written in the configuration file config.properties

Datasource=com.test.testdata.txtdata

4.2 Loading config file

public class Config {public static String data_source;static{map<string, string> Map = Propertieshandler.getpropertydata ("Config/config.properties");D Ata_source = Map.get ("DataSource");}}

4.3 Improve the Gettestdata () method in Testbase:

Private object[][] Gettestdata () {Datainterface testData = this.getdatainstance (Config.data_source); list<map<string, string>> listData = Testdata.gettestmethoddata (); object[][] Object = new object[ Listdata.size ()][];for (int i = 0; i < listdata.size (); i++) {Object[i] = new Object[]{listdata.get (i)};} return object;}

4.4 Run the Testdemo class again, the result is still the same. So far, we've implemented the option to change the contents of the configuration file to choose to load the data source.

Five. Switching multiple data sources

5.1 If there are two test methods in a test class, then after configuring the data source in the configuration file, it means that both test methods will load the same data source, but what if we want a test method to use the data source of the property file and another method to use the TXT data source? That is, you need to implement the global configuration, the local can select the data source again. I'm going to use the annotations in Java to make it happen. So let's first define a datasource annotation.

@Target (Elementtype.field) @Retention (retentionpolicy.runtime) public @interface DataSource {String value ();}

5.2 Parsing the annotation

public class DataSources {public static String Getdatasource (method method) {DataSource ds = Method.getannotation ( Datasource.class); if (ds! = null) {return ds.value ();} return null;}}

5.3 Use of this annotation

@DataSource ("Com.test.testdata.PropertiesData") @Test (dataprovider= "Dataprovider") public void Testdemo (map< String, string> param) {System.out.println (Param.get ("username")); System.out.println (Param.get ("password"));}

The Gettestdata () method in the 5.4 Testbase class is again changed to take advantage of the value parsed out on this annotation

Private object[][] Gettestdata (method method) {String Sourcekey = Datasources.getdatasource (method); if (sourcekey== NULL) {Sourcekey = Config.data_source;} Datainterface testData = this.getdatainstance (Sourcekey); list<map<string, string>> listData = Testdata.gettestmethoddata (); object[][] Object = new object[ Listdata.size ()][];for (int i = 0; i < listdata.size (); i++) {Object[i] = new Object[]{listdata.get (i)};} return object;}

This code can see that if the test method is labeled DataSource, the annotation value of the callout will prevail, otherwise the globally configured value will prevail.

5.5 Add a test method to the Testdemo to show the difference

public class Testdemo extends testbase{@DataSource ("Com.test.testdata.PropertiesData") @Test (dataprovider= " Dataprovider ") public void Testdemo (map<string, string> param) {System.out.println (Param.get (" username ")); System.out.println (Param.get ("password"));} @Test (dataprovider= "Dataprovider") public void TestDemo1 (map<string, string> param) {System.out.println ( Param.get ("username")); System.out.println (Param.get ("password"));}}

In the above test class, two test methods, one using the global configuration data source value, one with the annotated data source value. Everyone can run a look at the results.

Six. Engineering structure diagram:

As for the source code, everyone's own copy and paste it, but also as a knowledge of the consolidation.

Switching multiple data Sources in Java Automation testing

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.