
org.sitoolkit.tester.TestScriptCatalog Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2013 Monocrea Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sitoolkit.tester;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.sitoolkit.core.infra.repository.DocumentMapper;
import org.sitoolkit.core.infra.repository.DocumentRepository;
import org.sitoolkit.core.infra.repository.RowData;
import org.sitoolkit.core.infra.repository.TableData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.util.ResourceUtils;
/**
*
* @author yuichi.kuwahara
*/
@Component
@Scope("prototype")
public class TestScriptCatalog {
protected final Logger log = LoggerFactory.getLogger(getClass());
@Autowired
ApplicationContext appCtx;
@Autowired
OperationConverter operationConverter;
/**
* テストスクリプトの中から
* ケース番号のカラムを識別するためのプレフィックス
*/
private String caseNoPrefix = "ケース_";
/**
* テストスクリプト内で
* ケースのテストデータが記載された列番号
*/
private int caseNoColIndex;
/**
* テストスクリプト
*/
private List testScriptList = new ArrayList();
/**
* キー:スクリプトNo、値:スクリプトNoを持つTestScriptのtestScriptList内のインデックス
*/
private Map testScriptNoMap = new HashMap();
/**
* ケース番号マップ
* キー:ケース番号、値:テストデータ配列のインデックス
*/
private Map caseNoMap = new HashMap();
/**
* テストスクリプトの名前
*/
private String name;
/**
* 読み込みをケース番号のみに制限する場合にtrue
*/
private boolean loadCaseOnly;
/**
* カタログが最後に更新された日時
*/
private long lastModified;
/**
* テストスクリプトのファイル
*/
private File scriptFile;
private String sheetName;
public String getCaseNoPrefix() {
return caseNoPrefix;
}
public void setCaseNoPrefix(String caseNoPrefix) {
this.caseNoPrefix = caseNoPrefix;
}
public List getTestScriptList() {
return Collections.unmodifiableList(testScriptList);
}
public void addTestScript(TestScript testScript) {
if (testScript != null && testScript.getOperation() != null) {
testScriptList.add(testScript);
testScriptNoMap.put(testScript.getNo(), testScriptList.size() - 1);
}
}
public TestScript getTestScript(int index) {
return testScriptList.get(index);
}
public int getTestScriptCount() {
return testScriptList.size();
}
public Integer getScriptIndex(String scriptNo) {
return testScriptNoMap.get(scriptNo);
}
public void setTestScriptList(List testScriptList) {
this.testScriptList = testScriptList;
}
public Map getCaseNoMap() {
return caseNoMap;
}
public void setCaseNoMap(Map caseNoMap) {
this.caseNoMap = caseNoMap;
}
public boolean containsCaseNo(String caseNo) {
return caseNoMap.containsKey(caseNo);
}
public void reload() {
testScriptList.clear();
load(scriptFile.getAbsolutePath(), sheetName);
}
public void load(String testScriptPath, String sheetName) {
this.sheetName = sheetName;
if (testScriptPath.endsWith(".xlsx") || testScriptPath.endsWith("xls")) {
loadScriptFromExcel(testScriptPath, sheetName);
} else if (testScriptPath.endsWith(".csv")) {
loadScriptFromCsv(testScriptPath);
}
}
public void loadScriptFromExcel(String testScriptPath, String sheetName) {
RowData lastRow = null;
DocumentRepository repo = appCtx.getBean(DocumentRepository.class);
TableData table = repo.read(testScriptPath, sheetName);
DocumentMapper dm = appCtx.getBean(DocumentMapper.class);
RowData firstRow = table.getRows().iterator().next();
int testDataIndex = 0;
for (Map.Entry entry : firstRow.getData().entrySet()) {
if (entry.getKey().startsWith(getCaseNoPrefix())) {
String caseNo = StringUtils.substringAfter(entry.getKey(), getCaseNoPrefix());
caseNoMap.put(caseNo, testDataIndex++);
}
}
if (isLoadCaseOnly()) {
return;
}
for (RowData row : repo.read(testScriptPath, sheetName).getRows()) {
TestScript testScript = dm.map("testScript", row, TestScript.class);
addTestScript(testScript);
}
try {
scriptFile = ResourceUtils.getFile(testScriptPath);
lastModified = scriptFile.lastModified();
setName(scriptFile.getName());
} catch (FileNotFoundException e) {
throw new TestException(e);
}
}
public void loadScriptFromCsv(String testScriptPath) {
List lineList = null;
try {
scriptFile = ResourceUtils.getFile(testScriptPath);
lastModified = scriptFile.lastModified();
setName(scriptFile.getName());
lineList = FileUtils.readLines(scriptFile, "UTF-8");
} catch (IOException e) {
throw new TestException(e);
}
loadHeader(lineList.get(0));
if (isLoadCaseOnly()) {
return;
}
for (String line : lineList.subList(1, lineList.size())) {
if (line.startsWith("#")) {
log.info("テストスクリプトを除外します。{}", line);
continue;
}
String[] values = splitLine(line);
log.info("テストスクリプトを追加します。{}", Arrays.toString(values));
TestScript testScript = appCtx.getBean(TestScript.class);
testScript.setNo(CsvColumn.no.get(values));
testScript.setItemName(CsvColumn.itemName.get(values));
testScript.setOperation(
(Operation) operationConverter.convert(null, CsvColumn.operation.get(values)));
testScript.getLocator().setType(CsvColumn.locatorType.get(values));
testScript.getLocator().setValue(CsvColumn.locator.get(values));
testScript.setDataType(CsvColumn.dataType.get(values));
testScript.setScreenshotTiming(CsvColumn.screenshotTiming.get(values));
Map testDataMap = new HashMap();
String[] testData = ArrayUtils.subarray(values, caseNoColIndex, values.length);
for (Map.Entry entry : caseNoMap.entrySet()) {
String value = entry.getValue() < testData.length
? testData[entry.getValue()]
: StringUtils.EMPTY;
testDataMap.put(entry.getKey(), value);
}
log.debug("テストデータを追加します。{}", testDataMap);
testScript.setTestData(testDataMap);
addTestScript(testScript);
}
}
public boolean isLoadCaseOnly() {
return loadCaseOnly;
}
public void setLoadCaseOnly(boolean loadCaseOnly) {
this.loadCaseOnly = loadCaseOnly;
}
public boolean isScriptFileChanged() {
return lastModified != scriptFile.lastModified();
}
enum CsvColumn {
no(0),
itemName(1),
operation(2),
locatorType(3),
locator(4),
dataType(5),
screenshotTiming(6)
;
private int idx;
private CsvColumn(int idx) {
this.idx = idx;
}
public int getIdx() {
return idx;
}
public String get(String[] values) {
return values.length <= getIdx()
? StringUtils.EMPTY
: values[getIdx()];
}
}
/**
* テストスクリプトのヘッダー行から
* ケース番号とテストデータインデックスの対応を読み込み、 ケース番号マップに格納します。
*
* @param header ヘッダー行の文字列
*/
void loadHeader(String header) {
String[] cells = splitLine(header);
for (int i = 0; i < cells.length; i++) {
if (cells[i].startsWith(getCaseNoPrefix())) {
caseNoColIndex = i;
break;
}
}
int testDataIndex = 0;
for (String cell : ArrayUtils.subarray(cells, caseNoColIndex, cells.length)) {
String caseNo = StringUtils.substringAfter(cell, getCaseNoPrefix());
caseNoMap.put(caseNo, testDataIndex++);
}
log.info("{}件のケースを読み込みます。{}", caseNoMap.size(), caseNoMap.keySet());
}
/**
* 文字列を「,」(半角カンマ)または「\t」(タブ)で分割した文字配列を返します。
* 分割後の1要素の文字列が「"」(半角ダブルクオーテーション)で開始かつ終了していた場合は、 前後の「"」を除きます。
*
* @param line 分割対象の文字列
* @return 「,」(半角カンマ)または「\t」(タブ)で分割した文字配列
*/
String[] splitLine(String line) {
String[] values = line.split(",|\t");
for (int i = 0; i < values.length; i++) {
String value = values[i];
if (value.startsWith("\"") && value.endsWith("\"")) {
values[i] = value.substring(1, value.length() - 1);
}
}
return values;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getIndexByScriptNo(String no) {
return testScriptNoMap.get(no);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy