아래 편집기에서는 Java 자동화 테스트에서 여러 데이터 소스 간 전환에 대한 기사를 제공합니다(예제 설명). 편집자님이 꽤 좋다고 생각하셔서 지금 공유하고 모두에게 참고용으로 드리고자 합니다. 에디터를 따라가서 살펴볼까요
자동 테스트를 할 때 데이터 기반은 매우 중요한 개념입니다. 데이터가 스크립트에서 분리되면 엄청난 양의 데이터에 직면하게 되고 데이터 관리가 큰 문제가 되며, 데이터 소스가 여러 개 있을 수 있습니다. 개발 과정에서처럼 MYSQL에 연결해야 할 때도 있고 SQL SERVER에 연결해야 할 때도 있습니다. 다음 예에서는 데이터 소스로 시작하여 단계별로 설명합니다.
1. 외부 파일을 사용하여 데이터 기반을 작성하는 기본 방법
1.1 데이터 기반을 수행할 때, 우리는 JAVA의 속성 파일에 저장된 데이터를 사용합니다: data.properties
username=test password=123456
1.2 속성 파일을 구문 분석합니다.
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 저장하는 데 사용되는 TestBase 클래스를 작성합니다. TestNg 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; } }
데이터 유형(Listfe497e2be29e556eda152481563466e6>)을 사용하여 데이터 객체를 제공할 수 있는 클래스가 있는 한 이를 다음으로 변환할 수 있음을 알 수 있습니다. 2차원 Object[][] 배열은 실행할 테스트 메서드에 제공될 수 있습니다.
1.4 1.3에서 등장한 PropertiesData 클래스입니다. 이제 이 클래스를 구현해 보겠습니다
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 데이터 제공을 위한 기본 클래스가 있으므로, 테스트 방법을 결합하고 이 세 가지 기본 클래스를 융합하여 데이터 소스인 외부 파일의 완전한 예를 형성했습니다.
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")); } }
II 속성 파일을 txt 파일로 변경합니다. 구현
2.1 데이터 소스가 여러 개인 경우 txt를 사용하여 데이터를 저장하고 싶습니다. json 문자열은 txt에 저장됩니다. data.txt
{ "username":"test", "password":"123456" }
2.2 이 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 읽은 JSON 문자열을 구문 분석합니다(여기서 JAR 패키지인 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 TxtData 클래스를 사용합니다. 즉, PropertiesData가 있는 위치를 바꿉니다. TxtData 클래스와 함께 TestBase 클래스에 사용됩니다
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 TestDemo 테스트 클래스를 실행한 후 결과가 PropertiesData 클래스를 사용하기 전의 결과와 정확히 동일하다는 것을 알았습니다.
3. 인터페이스를 사용하여 구현
3.1 위의 두 데이터 소스에 대해 데이터 소스에 콘텐츠를 로드하고 로드된 데이터 유형은 List
public interface DataInterface { public List<Map<String, String>> getTestMethodData(); }
3.2 PropertiesData 클래스와 TxtData 클래스는 이 인터페이스를 구현해야 합니다
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 그런 다음 TestBase에서 뭔가 변경됩니다. 즉, 데이터 로딩을 생성하는 클래스 개체가 변경됩니다. 클래스 객체를 생성하는 새로운 방법입니다)
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 TestBase 클래스의 getTestData() 메서드가 다시 변경됩니다
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 TestDemo를 다시 실행하면 결과를 확인할 수 있습니다. 여전히 동일합니다. 따라서 지금은 데이터 로딩 클래스의 경로만 변경하면 됩니다.
4. 데이터 로딩 클래스의 경로를 구성합니다
4.1 이때 구성 파일 config.properties
DataSource=com.test.testdata.TxtData
4.2에 데이터 로딩 클래스의 경로를 작성한다고 생각할 수 있습니다. 구성 파일
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 TestBase의 getTestData() 메서드를 개선합니다.
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 TestDemo 클래스를 다시 실행하면 결과는 여전히 동일합니다. 지금까지는 로드할 데이터 소스를 선택하기 위해 구성 파일의 내용을 변경하는 방법을 구현했습니다.
5. 여러 데이터 소스 간 전환
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")); } }
上面的测试类中,两个测试方法,一个用了全局的配置数据源值,一个用了注解数据源值。大家可以运行的看看结果。
六. 工程结构图:
위 내용은 Java 자동화 테스트에서 여러 데이터 소스 간 전환에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!