Testng(三):外部データのロード

6018 ワード

1概要


1つの関数または1つのプロセスに対して、入力が与えられ、結果が返されます.
入力はパラメータや条件の組み合わせを指し、異なるテストシーンを構成します.
結果はプログラム対入力の処理であり,予想される結果と比較すると,現在のテストシーン機能の正確性がわかる.
これらのデータを外部ファイルとして格納すると、コードを再調整することなく追加を容易に修正できる

2 @DataProvider


Testngでは、@DataProviderがテストメソッドにデータを提供し、Object[][]のオブジェクトを返します.
そこで,@DataProviderメソッドでは,外部ファイルの読み取りを実現し,ファイルの内容をObject[][]形式で返すことが考えられる.
シナリオ:
  • 各メソッドは、それぞれのdataProviderに対応して、それぞれのデータファイルを読み出す.実装は容易であるが、コードが冗長であり、データファイルがばらばらであり、読み取りが頻繁である
  • すべてのメソッドは1つのdataProviderに対応し、dataProviderは呼び出したメソッド名に基づいて対応するテストデータを選択する.実装は複雑であり、並列を考慮する必要があるが、コードは
  • 簡略化されている.
    public class DataDriver {
        public static Map data = null;
    
        @DataProvider(name = "dp")
        public static Object[][] getData(Method method) {
            if (data == null || data.get(method.getName()) == null) {
                return new Object[][] {};
            }
            return data.get(method.getName());
        }
    }
    

    ここでは第2の方式を選択するが,外部ファイルを読み取ることなく,メソッド名による選択データのみを提供する.
    テスト・インスタンスが多すぎることを考慮すると、すべてのインスタンス・データを一度にメモリにロードすると膨大になるため、現在のcaseのデータのみをロードすることにします.

    3 TestCase


    @BeforeClassフェーズ初期化データ、@AfterClassフェーズ回収
    データを読み込むとき、ツールクラスがカプセル化されています.異なるデータ・キャリアに基づいて、複数のツール・クラスを記述できます.
    テスト方法はすべて同じdataProviderを指して、dataProviderClass属性を加えることを忘れないでください
    public class IpCase {
        @BeforeClass
        public void setup() {
            String caseFullName = this.getClass().getName();
            String caseName = caseFullName.substring(caseFullName.lastIndexOf('.') + 1);
            DataDriver.data = ExcelUtil.readExcel(caseName);
        }
    
        @AfterClass
        public void teardown() {
            DataDriver.data.clear();
        }
    
        @Test(dataProvider = "dp", dataProviderClass = DataDriver.class)
        public void isIpv41(String ip, boolean expected) {
            boolean actual = ip != null;
            Assert.assertEquals(actual, expected);
        }
    
        @Test(dataProvider = "dp", dataProviderClass = DataDriver.class)
        public void isIpv6(String ip, boolean expected) {
            boolean actual = ip != null;
            Assert.assertEquals(actual, expected);
        }
    }
    

    4 Excelファイルの処理


    データストレージは、Excel、TXT、データベースを使用することができます.メンテナンスが容易で、読みやすいキャリアを選択すればいいです.
    ここではexcelと暫定してpoiパケットを用いて解析する
    Excelの名称要求はTestCaseと一致し(IpCase.xlsx)、sheet名称は各試験方法(isIpv 4,isIpv 6)に対応し、これにより方法名に基づいて相応の試験データを取得することができる
    isIpv 4対応データは以下の通りです.
    IP
    Expected
    1.1.1.1
    TRUE
    2.2.2.256
    FALSE
    isIpv 6対応データは以下の通り
    IP
    Expected
    ::1
    TRUE
    FF01::1101
    TRUE
    public class ExcelUtil {
        private static final String SUFFIX_2007 = ".xlsx";
    
        public static Map readExcel(String caseName) {
            Map result = new HashMap<>();
            InputStream is = null;
    
            try {
                is = ExcelUtil.class.getClassLoader().getResourceAsStream(String.format("TestCase/%s%s", caseName, SUFFIX_2007));
                XSSFWorkbook workbook = new XSSFWorkbook(is);
    
                for (int sheetNum = 0; sheetNum < workbook.getNumberOfSheets(); sheetNum++) {
                    Sheet sheet = workbook.getSheetAt(sheetNum);
    
                    int rows = sheet.getLastRowNum();
                    if (rows <= 0) continue;
                    int cols = sheet.getRow(1).getLastCellNum();
                    Object[][] data = new Object[rows][cols];
    
                    for (int rowNum = 1; rowNum <= rows; rowNum++) {
                        Row row = sheet.getRow(rowNum);
                        for (int celNum = 0; celNum < cols; celNum++) {
                            Cell cell = row.getCell(celNum);
    
                            Object cellValue = null;
                            CellType cellType = cell.getCellTypeEnum();
                            if (cellType == CellType.BOOLEAN) {
                                cellValue = cell.getBooleanCellValue();
                            } else if (cellType == CellType.STRING) {
                                cellValue = cell.getStringCellValue();
                            } else if (cellType == CellType.NUMERIC) {
                                cellValue = cell.getNumericCellValue();
                            } else {
                                cellValue = "";
                            }
    
                            data[rowNum - 1][celNum] = cellValue;
                        }
                    }
                    result.put(sheet.getSheetName(), data);
                }
            } catch (IOException e) {
                System.out.println("File not found: " + caseName);
            } finally {
                if (is != null) {
                    try {
                        is.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return result;
        }
    }
    

    5@Test注記変換


    テストメソッドがデータをロードする必要がある場合、プロパティdataProvider = "dp", dataProviderClass = DataDriver.classを指定する必要があります.
    手間を省くためIAnnotationTransformerリスナーをご利用いただけます
  • 約定メソッド名に「Dp」、「_dp」または他の好きな接尾辞が含まれている場合、@Test注記にdataProviderプロパティ
  • を自動的に追加します.
  • group名を指定し、group=dpのテスト方法が属性
  • を自動的に補完すると仮定する.
    public class TestAnnotationTransformer implements IAnnotationTransformer {
        @Override
        public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) {
            String[] groups = annotation.getGroups();
            for(String group: groups) {
                if (group.equals("dp")) {
                    annotation.setDataProvider("dp");
                    annotation.setDataProviderClass(DataDriver.class);
                    break;
                }
            }
        }
    }
    

    6次の最適化

  • 現在はexcel解析ツールクラスのみで、2007版のみをサポートしており、2007以下のバージョンは
  • をサポートしています.
  • Excelデータ型判定、浮動小数点数、日付などのタイプは
  • を強化する必要がある.
  • 並列実行時、DataDriver.Dataが競合する可能性があります.Caseクラスの
  • に参照を移行する必要があります.