Heim  >  Artikel  >  Java  >  Ausführliche Erläuterung des Wechsels zwischen mehreren Datenquellen beim automatisierten Java-Testen

Ausführliche Erläuterung des Wechsels zwischen mehreren Datenquellen beim automatisierten Java-Testen

黄舟
黄舟Original
2017-10-09 10:18:251981Durchsuche

Der folgende Editor bringt Ihnen einen Artikel zum Wechseln zwischen mehreren Datenquellen beim automatisierten Java-Testen (Erklärung mit Beispielen). Der Herausgeber findet es ziemlich gut, deshalb teile ich es jetzt mit Ihnen und gebe es als Referenz. Lassen Sie uns dem Editor folgen und einen Blick darauf werfen.

Bei der Durchführung automatisierter Tests ist die Datensteuerung ein sehr wichtiges Konzept Ein großes Problem, und Datenquellen können mit mehreren Problemen konfrontiert sein. Manchmal müssen Sie eine Verbindung zu MYSQL herstellen, und manchmal müssen Sie eine Verbindung zu SQL SERVER herstellen. Im folgenden Beispiel beginnen wir mit einer Datenquelle und demonstrieren diese Schritt für Schritt:

1. Die grundlegende Schreibmethode zur Verwendung externer Dateien zur Steuerung von Daten

1.1 Wenn wir datengesteuert sind, speichern wir die Daten in der JAVA-Eigenschaftendatei: data.properties


username=test
password=123456

1.2 Analysieren Sie die Eigenschaftendatei


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;
 }
  
 /**
  * 将property转换成Map
  * @param key
  * @return
  */
 @SuppressWarnings({ "rawtypes", "unchecked" })
 public static Map<String, String> getPropertyData(String filePath){
  try{
   return new HashMap<String, String>((Map)PropertiesHandler.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 Schreiben eine TestBase-Klasse, die zum Speichern des DataProvider


public class TestBase {
  
 @DataProvider
 public 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;
 }
  
}

verwendet wird, um TestNg zu speichern Als Klasse kann ich einen Datentyp bereitstellen: Die Datenobjekte von Listfe497e2be29e556eda152481563466e6> können in ein zweidimensionales Array von Object[][] konvertiert werden, das der Testmethode zur Ausführung bereitgestellt werden kann .

1.4 Eine PropertiesData-Klasse erschien in 1.3. Jetzt implementieren wir diese Klasse


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;
 }
  
}

1,5  Zu den oben genannten gehören Datenanalyseklassen, Datenladeklassen und Datenbereitstellungsgrundklassen. Daher kombinieren wir die Testmethoden, um diese drei Grundklassen zu integrieren und ein vollständiges Beispiel zu bilden einer externen Datei als Datenquelle:


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"));
 }
  
}

2. Implementierung des Ersetzens von Property-Dateien durch TXT-Dateien

2.1 Wenn es mehrere Datenquellen gibt, möchte ich txt zum Speichern der Daten verwenden. Ein JSON-String wird in txt gespeichert: data.txt


{
 "username":"test",
 "password":"123456"
}

2.2 Lesen Sie diese TXT-Datei vor


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 Analysieren Sie die gelesene JSON-Zeichenfolge (hier müssen Sie ein JAR-Paket verwenden, 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 Verwenden Sie die TxtData-Klasse, dh ersetzen Sie die PropertiesData-Klasse in der TestBase-Klasse durch die TxtData-Klasse


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 Nach dem Ausführen der TestDemo-Testklasse wurde festgestellt, dass die Ergebnisse genau mit denen vor der Verwendung der PropertiesData-Klasse identisch sind.

3. Verwenden Sie Schnittstellen zum Implementieren von

3.1 Die beiden oben genannten Datenquellen in der Datenquelle Nach dem Inhalt Wird geladen und der geladene Datentyp ist: Listfe497e2be29e556eda152481563466e6>, wir müssen nur die Ladeklasse der Datenquelle in der TestBase-Klasse ersetzen. Auf diese Weise können wir JAVA verwenden, um unseren Code mithilfe der Schnittstelle zu rekonstruieren Im Inneren müssen wir natürlich zuerst eine Schnittstelle haben


public interface DataInterface {
 public List<Map<String, String>> getTestMethodData();
}

3.2 Unsere PropertiesData-Klasse und TxtData-Klasse müssen diese Schnittstelle natürlich implementieren


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 Dann ändert sich etwas in TestBase, das heißt, das Klassenobjekt, das das Laden von Daten generiert, wird geändert, wir fügen eine neue Methode in TestBase hinzu (Dies ist eine neue Möglichkeit, Klassenobjekte zu generieren)


private DataInterface getDataInstance(String key){
 DataInterface data = null;
 try {
  data = (DataInterface) Class.forName(key).newInstance();
 } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
  e.printStackTrace();
 }
 return data;
}

3.4 Die getTestData()-Methode in der TestBase-Klasse Es ist Zeit, sie erneut zu ändern


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 Führen Sie TestDemo erneut aus und Sie werden feststellen, dass das Ergebnis immer noch dasselbe ist. Daher müssen Sie zu diesem Zeitpunkt nur den Pfad der Datenladeklasse ändern.

4. Konfigurierbarer Pfad der Datenladeklasse

4.1 Zu diesem Zeitpunkt können wir über den Pfad der Datenladeklasse nachdenken Geschrieben in der Konfigurationsdatei config.properties


DataSource=com.test.testdata.TxtData

4.2 Laden der Konfigurationsdatei


public class Config {
  
 public static String DATA_SOURCE;
  
 static{
  Map<String, String> map = PropertiesHandler.getPropertyData("config/config.properties");
  DATA_SOURCE = map.get("DataSource");
 }
  
}

4.3 Verbessern Sie die getTestData()-Methode 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 Führen Sie die TestDemo-Klasse erneut aus, und das Ergebnis ist immer noch dasselbe. Bisher haben wir die Änderung des Inhalts in der Konfigurationsdatei implementiert, um die zu ladende Datenquelle auszuwählen.

5. Wechseln zwischen mehreren Datenquellen

5.1 如果一个测试类里有两个测试方法,那么在配置文件里配置好数据源后,就表示这两个测试方法都将会加载同样的数据源,但如果我们希望一个测试方法用属性文件的数据源,另一个方法用TXT的数据源,这个如何办?也就是需要实现在全局配置化后,局部可再次选择数据源。我将会利用到JAVA里的注解,来实现。所以我们先定义一个DataSource的注解


@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DataSource {
 String value();
}

5.2 解析该注解


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 该注解的使用


@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"));
}

5.4 TestBase类里的getTestData()方法再次的更改,要利用上这个注解解析出来的值


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;
}

这段代码可以看到,如果测试方法标注DataSource,则会以标注的注解值为准,否则则会以全局配置的值为准。

5.5 在TestDemo里多加一个测试方法,以示区别


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"));
 }
  
}

上面的测试类中,两个测试方法,一个用了全局的配置数据源值,一个用了注解数据源值。大家可以运行的看看结果。

六. 工程结构图:

Das obige ist der detaillierte Inhalt vonAusführliche Erläuterung des Wechsels zwischen mehreren Datenquellen beim automatisierten Java-Testen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn