package org.test4j.testng; import java.util.Map; import org.test4j.module.ICore; import org.test4j.module.core.ICoreInitial; import org.test4j.module.core.TestContext; import org.test4j.module.database.IDatabase; import org.test4j.module.jmockit.IMockict; import org.test4j.module.spring.ISpring; import org.test4j.spec.ISpec; import org.test4j.spec.ISpecExecutorFactory; import org.test4j.spec.SharedData; import org.test4j.spec.inner.IScenario; import org.test4j.spec.inner.ISpecMethod; import org.test4j.spec.inner.ISpecMethod.SpecMethodID; import org.test4j.spec.inner.ISpecPrinter; import org.test4j.tools.datagen.DataProviderIterator; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; @SuppressWarnings({ "unchecked" }) public abstract class JSpec extends Test4JCore implements ISpec, ICore, IMockict, ISpring, IDatabase { static ISpecExecutorFactory specFactory = ICoreInitial.initSpecExecutorFactory(); private final Map<SpecMethodID, ISpecMethod> specMethods; private Map<String, Object> stepsInstances; private static ThreadLocal<ISpecPrinter> threadPrinter = new ThreadLocal<ISpecPrinter>(); public JSpec() { this.specMethods = specFactory.findMethodsInSpec(this.getClass()); } @Override public Object getStepsInstance(String stepClazzName) { return this.stepsInstances.get(stepClazzName); } /** * 用来初始化共享的数据结构<br> * 允许子类进行覆盖 */ protected void initSharedData() { } @Override public SharedData getSharedData() { return new SharedData.EmptyData(); } public abstract void runScenario(IScenario scenario) throws Throwable; @BeforeClass(alwaysRun = true) public void initPrinter() { } @AfterClass(alwaysRun = true) public static void cleanSpecPrinter() { getPrinter().printSummary(TestContext.currTestedClazz()); threadPrinter.remove(); } @DataProvider public DataProviderIterator<IScenario> story() { DataProviderIterator<IScenario> it = specFactory.findScenario(this.getClass()); return it; } public void run(IScenario scenario) throws Throwable { this.initSharedData(); this.stepsInstances = specFactory.newSteps(this); specFactory.runScenario(this, scenario, specMethods, getPrinter()); } static ISpecPrinter getPrinter() { ISpecPrinter printer = threadPrinter.get(); if (printer == null) { printer = specFactory.newSpecPrinter(); threadPrinter.set(printer); } return printer; } }