Skip to content

Commit

Permalink
单元测试增加sqlInit和sqlInput支持
Browse files Browse the repository at this point in the history
  • Loading branch information
entropy-cloud committed Aug 9, 2024
1 parent 28d3de4 commit 1e59816
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 85 deletions.
7 changes: 6 additions & 1 deletion docs/dev-guide/autotest.md
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ public @interface EnableSnapshot {
/**
* 是否自动执行input目录下的sql文件
*/
boolean sqlInit() default true;
boolean sqlInput() default true;

/**
* 是否自动将input/tables目录下的数据插入到数据库中
Expand All @@ -316,6 +316,11 @@ public @interface EnableSnapshot {
}
```

### SQL初始化
init目录下的`xxx.sql`会在自动建表之前执行,而input目录下的`xxx.sql`会在自动建表之后执行。

在sql文件中,可以使用 `@include: ../init.sql`这种方法引入其他目录下的sql文件。

## 四. 数据变体

数据驱动测试的一个非常大优势在于,它很容易实现对边缘场景的细化测试。
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
/**
* 是否自动执行input目录下的sql文件
*/
boolean sqlInput() default true;

boolean sqlInit() default true;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ public class AutoTestCase extends BaseTestCase {
private boolean localDb;
private boolean tableInit;
private boolean sqlInit;
private boolean sqlInput;
private boolean saveOutput;

public String getTestMethod() {
Expand Down Expand Up @@ -154,7 +155,7 @@ public void initDao() {
if (localDb || tableInit || sqlInit) {
LOG.info("\n========= autotest restore data from snapshot ============");
if (daoProvider != null) {
new AutoTestCaseDataBaseInitializer(variant, localDb, tableInit, sqlInit, caseData, daoProvider,
new AutoTestCaseDataBaseInitializer(variant, localDb, tableInit, sqlInit, sqlInput, caseData, daoProvider,
jdbcTemplate).initialize();
}
}
Expand Down Expand Up @@ -267,6 +268,10 @@ public void setSqlInit(boolean sqlInit) {
this.sqlInit = sqlInit;
}

public void setSqlInput(boolean sqlInput){
this.sqlInput = sqlInput;
}

/**
* 根据文件名,在input目录下读取json格式的数据文件。
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,7 @@ public interface AutoTestConstants {

char PATTERN_PREFIX = '@';

String INCLUDE_DIRECTIVE_PREFIX = "@include:";

String CFG_GRAPHQL_IGNORE_MILLIS_IN_TIMESTAMP = "nop.graphql.ignore-millis-in-timestamp";
}
Original file line number Diff line number Diff line change
Expand Up @@ -267,11 +267,24 @@ public List<File> getInputSqlFiles(String variant) {
if (isDefaultVariant(variant))
return getInputSqlFiles();

List<File> files = getInputTableFiles();
List<File> files = getInputSqlFiles();
List<File> varFiles = getFiles("input/" + variant, ".sql");
return mergeFiles(files, varFiles);
}

public List<File> getInitSqlFiles(String variant) {
if (isDefaultVariant(variant))
return getInitSqlFiles();

List<File> files = getInitSqlFiles();
List<File> varFiles = getFiles("init/" + variant, ".sql");
return mergeFiles(files, varFiles);
}

private List<File> getInitSqlFiles() {
return getFiles("init", ".sql");
}

private List<File> getInputSqlFiles() {
return getFiles("input", ".sql");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,34 +33,44 @@
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;

import static io.nop.autotest.core.AutoTestConstants.INCLUDE_DIRECTIVE_PREFIX;
import static io.nop.autotest.core.AutoTestErrors.ARG_FILE;
import static io.nop.autotest.core.AutoTestErrors.ARG_TABLE_NAME;
import static io.nop.autotest.core.AutoTestErrors.ERR_AUTOTEST_NO_DAO_FOR_TABLE;

@SuppressWarnings("rawtypes")
public class AutoTestCaseDataBaseInitializer {
static final Logger LOG = LoggerFactory.getLogger(AutoTestCaseDataBaseInitializer.class);

private final boolean localDb;
private final boolean tableInit;
private final boolean sqlInit;
private final boolean sqlInput;
private final AutoTestCaseData caseData;
private final IDaoProvider daoProvider;
private final IJdbcTemplate jdbcTemplate;
private final String variant;

public AutoTestCaseDataBaseInitializer(String variant, boolean localDb, boolean tableInit, boolean sqlInit,
public AutoTestCaseDataBaseInitializer(String variant, boolean localDb, boolean tableInit,
boolean sqlInit, boolean sqlInput,
AutoTestCaseData caseData, IDaoProvider daoProvider, IJdbcTemplate jdbcTemplate) {
this.variant = variant;
this.localDb = localDb;
this.tableInit = tableInit;
this.sqlInit = sqlInit;
this.sqlInput = sqlInput;
this.caseData = caseData;
this.daoProvider = daoProvider;
this.jdbcTemplate = jdbcTemplate;
}

public void initialize() {
if (sqlInit) {
executeInitSqls();
}

if (localDb) {
// 1. 建表
createTables();
Expand All @@ -71,9 +81,9 @@ public void initialize() {
loadInputData();
}

if (sqlInit) {
if (sqlInput) {
// 3. 执行初始化sql语句
executeInitSqls();
executeInputSqls();
}
}

Expand Down Expand Up @@ -104,7 +114,7 @@ void createTable(IDialect dialect, IEntityModel entityModel) {
try {
jdbcTemplate.executeUpdate(new SQL(sql));
} catch (NopException e) {
if(jdbcTemplate.existsTable(null,entityModel.getTableName()))
if (jdbcTemplate.existsTable(null, entityModel.getTableName()))
return;

if (e.getErrorCode().equals(DaoErrors.ERR_SQL_BAD_SQL_GRAMMAR.getErrorCode())) {
Expand Down Expand Up @@ -179,13 +189,42 @@ private IOrmEntity newEntityFromRow(Map<String, Object> row, IOrmEntityDao<IOrmE
}

private void executeInitSqls() {
List<File> files = caseData.getInitSqlFiles(variant);
executeSqlFiles(files);
}

private void executeInputSqls() {
List<File> files = caseData.getInputSqlFiles(variant);
executeSqlFiles(files);
}

private void executeSqlFiles(List<File> files) {
for (File file : files) {
String sql = FileHelper.readText(file, null);
if (StringHelper.isBlank(sql))
continue;

sql = resolveSql(file, sql);
jdbcTemplate.executeMultiSql(new SQL(sql));
}
}

private String resolveSql(File file, String sql) {
if (!sql.contains(INCLUDE_DIRECTIVE_PREFIX))
return sql;

List<String> list = StringHelper.stripedSplit(sql, '\n');
list = list.stream().map(str -> {
if (str.startsWith(INCLUDE_DIRECTIVE_PREFIX)) {
String path = str.substring(INCLUDE_DIRECTIVE_PREFIX.length()).trim();
String absPath = StringHelper.absolutePath(file.getAbsolutePath().replace('\\', '/'),
path.replace('\\', '/'));
File includeFile = new File(absPath);
return FileHelper.readText(includeFile, null);
} else {
return str;
}
}).collect(Collectors.toList());
return StringHelper.join(list, "\n");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ protected void configExecutionMode(TestInfo testInfo) {
if (enableSnapshot != null && !CFG_AUTOTEST_DISABLE_SNAPSHOT.get()) {
setCheckOutput(enableSnapshot.checkOutput());
setLocalDb(enableSnapshot.localDb());
setSqlInput(enableSnapshot.sqlInput());
setSqlInit(enableSnapshot.sqlInit());
setTableInit(enableSnapshot.tableInit());
setSaveOutput(enableSnapshot.saveOutput());
Expand All @@ -95,6 +96,7 @@ protected void configExecutionMode(TestInfo testInfo) {
setCheckOutput(false);
setLocalDb(false);
setSqlInit(false);
setSqlInput(false);
setTableInit(false);
setSaveOutput(true);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,15 @@
*/
package io.nop.dyn.service.codegen;

import io.nop.api.core.annotations.autotest.EnableSnapshot;
import io.nop.api.core.annotations.autotest.NopTestConfig;
import io.nop.api.core.annotations.core.Description;
import io.nop.api.core.beans.ApiRequest;
import io.nop.api.core.beans.ApiResponse;
import io.nop.api.core.beans.FieldSelectionBean;
import io.nop.api.core.util.FutureHelper;
import io.nop.autotest.junit.JunitAutoTestCase;
import io.nop.autotest.junit.JunitBaseTestCase;
import io.nop.commons.type.StdSqlType;
import io.nop.core.lang.sql.SQL;
import io.nop.core.reflect.bean.BeanTool;
import io.nop.dao.api.IDaoProvider;
import io.nop.dao.jdbc.IJdbcTemplate;
Expand All @@ -33,7 +32,6 @@
import jakarta.inject.Inject;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;

import java.util.Iterator;
import java.util.List;
Expand All @@ -60,12 +58,6 @@ public class TestDynCodeGenRelation extends JunitAutoTestCase {
@Inject
IJdbcTemplate jdbcTemplate;

@Override
public void init(TestInfo testInfo) {
super.init(testInfo);
initDb();
}

public void testGen(OrmRelationType relationType) {
ormTemplate.runInSession(() -> {
saveRelModule(relationType);
Expand All @@ -80,6 +72,10 @@ public void testOneToOneRelation() {
this.testManyToOneRelation();
}

/**
* 自动录制的input实体RoleEntity实际上是动态创建的,所以录制完成后需要删除input目录下的role-entity.csv等,否则重放的时候会报实体不存在。
*/
@EnableSnapshot
@Test
public void testManyToOneRelation() {

Expand All @@ -97,6 +93,7 @@ public void testManyToOneRelation() {
assertEquals(2, items.size());
}

@EnableSnapshot
@Test
public void testOneToManyRelation() {

Expand All @@ -114,6 +111,7 @@ public void testOneToManyRelation() {
assertEquals(1, items.size());
}

@EnableSnapshot(saveOutput = true)
@Test
public void testManyToManyRelation() {

Expand All @@ -131,73 +129,6 @@ public void testManyToManyRelation() {
assertEquals(1, items.size());
}

private void initDb() {

if (jdbcTemplate.existsTable("", "USER_ENTITY")) {
return;
}

String userSql = "CREATE TABLE USER_ENTITY(\n"
+ " SID VARCHAR(32) COMMENT '主键ID' ,\n"
+ " USER_NAME VARCHAR(100) COMMENT '用户名' ,\n"
+ " USER_AGE INTEGER default '1' COMMENT '用户年龄' ,\n"
+ " ROLE_ID VARCHAR(200) COMMENT '角色 ID' ,\n"
+ " STATUS INTEGER default '1' COMMENT '状态' ,\n"
+ " VERSION INTEGER COMMENT '数据版本' ,\n"
+ " CREATED_BY VARCHAR(50) COMMENT '创建人' ,\n"
+ " CREATE_TIME TIMESTAMP COMMENT '创建时间' ,\n"
+ " UPDATED_BY VARCHAR(50) COMMENT '修改人' ,\n"
+ " UPDATE_TIME TIMESTAMP COMMENT '修改时间' ,\n"
+ " constraint PK_USER_ENTITY_ID primary key (sid)\n"
+ " )";

String insertSql = "INSERT INTO USER_ENTITY (sid, user_name, user_age, role_id, STATUS, VERSION, CREATED_BY, CREATE_TIME, UPDATED_BY, UPDATE_TIME) VALUES "
+ "('1', '小明', 1, '123', 1, 1, '小明', '2021-09-01 00:00:00', '小明', '2021-09-01 00:00:00'),"
+ "('2', '小李', 200, '123', 1, 1, '小李', '2021-09-01 00:00:00', '小李', '2021-09-01 00:00:00')";


String roleSql = "CREATE TABLE ROLE_ENTITY(\n"
+ " SID VARCHAR(32) COMMENT '主键ID' ,\n"
+ " ROLE_NAME VARCHAR(100) COMMENT '角色名称' ,\n"
+ " ROLE_KEY VARCHAR(100) COMMENT '角色 key' ,\n"
+ " STATUS INTEGER default '1' COMMENT '状态' ,\n"
+ " VERSION INTEGER COMMENT '数据版本' ,\n"
+ " CREATED_BY VARCHAR(50) COMMENT '创建人' ,\n"
+ " CREATE_TIME TIMESTAMP COMMENT '创建时间' ,\n"
+ " UPDATED_BY VARCHAR(50) COMMENT '修改人' ,\n"
+ " UPDATE_TIME TIMESTAMP COMMENT '修改时间' ,\n"
+ " constraint PK_ROLE_ENTITY_ID primary key (sid)\n"
+ " )";

String insertRoleSql = "INSERT INTO ROLE_ENTITY (sid, role_name, role_key, STATUS, VERSION, CREATED_BY, CREATE_TIME, UPDATED_BY, UPDATE_TIME) VALUES "
+ " ('123', '开发角色2', '1', 1, 1, 'development', '2021-09-01 00:00:00', 'development', '2021-09-01 00:00:00')";
// + " ('12356', '测试角色', '2', 1, 1, 'test', '2021-09-01 00:00:00', 'test', '2021-09-01 00:00:00') ";

String manySql = "CREATE TABLE USER_MANY_ROLE(\n"
+ " SID VARCHAR(32) COMMENT '主键ID' ,\n"
+ " USER_ID VARCHAR(32) COMMENT '用户 ID' ,\n"
+ " ROLE_ID VARCHAR(32) COMMENT '角色 ID' ,\n"
+ " STATUS INTEGER default '1' COMMENT '状态' ,\n"
+ " VERSION INTEGER COMMENT '数据版本' ,\n"
+ " CREATED_BY VARCHAR(50) COMMENT '创建人' ,\n"
+ " CREATE_TIME TIMESTAMP COMMENT '创建时间' ,\n"
+ " UPDATED_BY VARCHAR(50) COMMENT '修改人' ,\n"
+ " UPDATE_TIME TIMESTAMP COMMENT '修改时间' ,\n"
+ " constraint PK_USER_MANY_ROLE_ID primary key (user_id, role_id)\n"
+ " )";
String insertManySql = "INSERT INTO USER_MANY_ROLE (sid, user_id, role_id, STATUS, VERSION, CREATED_BY, CREATE_TIME, UPDATED_BY, UPDATE_TIME) VALUES "
+ "('1233123', '1', '123', 1, 1, '小明', '2021-09-01 00:00:00', '小明', '2021-09-01 00:00:00'),"
+ "('1412414', '255', '123', 1, 1, '小明', '2021-09-01 00:00:00', '小明', '2021-09-01 00:00:00')";

System.out.println(userSql + "\n" + insertSql + "\n" + roleSql + "\n" + insertRoleSql + "\n" + manySql + "\n" + insertManySql);
jdbcTemplate.executeMultiSql(new SQL(userSql));
jdbcTemplate.executeUpdate(new SQL(insertSql));
jdbcTemplate.executeMultiSql(new SQL(roleSql));
jdbcTemplate.executeUpdate(new SQL(insertRoleSql));
jdbcTemplate.executeMultiSql(new SQL(manySql));
jdbcTemplate.executeUpdate(new SQL(insertManySql));
}

private void saveRelModule(OrmRelationType ormRelationType) {
NopDynModule module = new NopDynModule();
module.setModuleName("relation-demo");
Expand Down Expand Up @@ -315,11 +246,13 @@ private void addManyToManyRelation(NopDynModule module) {
NopDynEntityMeta roleEntity = iterator.next();
NopDynEntityMeta middleEntity = iterator.next();

module.getEntityMetas().remove(middleEntity);

addRelation(OrmRelationType.m2m, "userRoles", "测试用户对多对关联",
"sid", "userId", userEntity, middleEntity, "USER_MANY_ROLE");
"sid", "userId", userEntity, roleEntity, "USER_MANY_ROLE");

addRelation(OrmRelationType.m2m, "roleUsers", "测试角色对多对关联",
"sid", "roleId", roleEntity, middleEntity, "USER_MANY_ROLE");
"sid", "roleId", roleEntity, userEntity, "USER_MANY_ROLE");
}

private NopDynPropMeta addProp(NopDynEntityMeta entityMeta, String propName, StdSqlType sqlType, int precision) {
Expand Down

0 comments on commit 1e59816

Please sign in to comment.