L'éditeur suivant vous proposera un article sur la commutation entre plusieurs sources de données dans les tests automatisés Java (explication avec exemples). L'éditeur le trouve plutôt bon, je vais donc le partager avec vous maintenant et le donner comme référence pour tout le monde. Suivons l'éditeur pour y jeter un œil
Lors de tests automatisés, la gestion des données est un concept très important. Lorsque les données sont séparées du script, face à l'énorme quantité de données, la gestion des données devient un gros problème. problème. Problème, et les sources de données peuvent en rencontrer plusieurs. Tout comme pendant le processus de développement, vous devez parfois vous connecter à MYSQL et parfois vous devez vous connecter à SQL SERVER. Comment basculer rapidement ? Dans l'exemple suivant, nous allons commencer par une source de données et la démontrer étape par étape :
1 La méthode d'écriture de base consistant à utiliser des fichiers externes pour piloter des données.
1.1 Lorsque nous sommes pilotés par les données, nous stockons les données dans le fichier de propriétés JAVA : data.properties
username=test password=123456
1.2 Analyser le fichier de propriétés
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 Écrire une classe TestBase , qui est utilisée pour stocker le 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; } }
utilisé pour stocker TestNg. une classe, je peux fournir un type de données : les objets de données de List
1.4 Une classe PropertiesData est apparue dans la version 1.3. Implémentons maintenant cette classe
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 Parmi ce qui précède, il existe des classes d'analyse de données, des classes de chargement de données et des classes de base fournissant des données, nous combinons donc les méthodes de test pour intégrer ces trois classes de base, formant un exemple complet. d'un fichier externe comme source de données :
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. Mise en place du remplacement des fichiers de propriétés par des fichiers txt
2.1 S'il existe plusieurs sources de données, je souhaite utiliser txt pour stocker les données. Une chaîne json est stockée dans txt : data.txt <. 🎜>
{ "username":"test", "password":"123456" }
2.2 Lisez ce fichier txt
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 Analyser la chaîne JSON lue (vous devez utiliser un package JAR ici, 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 Utiliser la classe TxtData, c'est-à-dire remplacer la classe PropertiesData dans la classe TestBase par la classe TxtData
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 Après avoir exécuté la classe de test TestDemo, il s'avère que les résultats sont exactement les mêmes que ceux qui apparaissaient avant d'utiliser la classe PropertiesData.
3. Utiliser des interfaces pour implémenter 3.1 Les deux sources de données ci-dessus, dans la source de données Après le contenu est chargé et le type de données chargé est : List
public interface DataInterface { public List<Map<String, String>> getTestMethodData(); }
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; } }
private DataInterface getDataInstance(String key){ DataInterface data = null; try { data = (DataInterface) Class.forName(key).newInstance(); } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { e.printStackTrace(); } return data; }
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; }
4. Configurable le chemin de la classe de chargement de données 4.1 À ce stade, nous pouvons réfléchir au chemin de la classe de chargement de données Écrit dans le fichier de configuration config.properties
DataSource=com.test.testdata.TxtData
public class Config { public static String DATA_SOURCE; static{ Map<String, String> map = PropertiesHandler.getPropertyData("config/config.properties"); DATA_SOURCE = map.get("DataSource"); } }
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; }
5. Basculer entre plusieurs sources de données 5.1 如果一个测试类里有两个测试方法,那么在配置文件里配置好数据源后,就表示这两个测试方法都将会加载同样的数据源,但如果我们希望一个测试方法用属性文件的数据源,另一个方法用TXT的数据源,这个如何办?也就是需要实现在全局配置化后,局部可再次选择数据源。我将会利用到JAVA里的注解,来实现。所以我们先定义一个DataSource的注解 5.2 解析该注解 5.3 该注解的使用 5.4 TestBase类里的getTestData()方法再次的更改,要利用上这个注解解析出来的值 这段代码可以看到,如果测试方法标注DataSource,则会以标注的注解值为准,否则则会以全局配置的值为准。 5.5 在TestDemo里多加一个测试方法,以示区别 上面的测试类中,两个测试方法,一个用了全局的配置数据源值,一个用了注解数据源值。大家可以运行的看看结果。 六. 工程结构图: Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DataSource {
String value();
}
public class DataSources {
public static String getDataSource(Method method){
DataSource ds = method.getAnnotation(DataSource.class);
if(ds != null){
return ds.value();
}
return null;
}
}
@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"));
}
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;
}
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"));
}
}