另一个可行的选项是将 JUnit 参数化应用到您的测试中。我目前的理解是,实现的参数总是按照它们提供的顺序执行。
使用该概念,您可以让 JUnit 实现接受 URL 作为构造函数参数,并根据提供的参数在内部分叉测试。
为了确保您使用相同的 WebDriver 引用,它可能需要是静态的 @BeforeClass/@AfterClass 声明。这样您就可以将参数链接在一起,有效地测试“从上一个测试我在 X 页上。在这里我将执行任务 Y。在这个测试结束时,我将在 Z 页上,或处于状态 A”。
在单元级测试中,我肯定会说这种解决方案的形式不好,但是当您集成像 Selenium 这样的工具时,您就开始在集成测试级别上采取行动。我自己对这个概念还很陌生,但在集成测试级别,模块化规则似乎有点模糊,因为你会有依赖的条件。
我很好奇,所以我试了一下。如果我们假设我们可以将应用程序视为与测试相关的静态资源,它就像我想的那样。
package demo.testing;
import java.util.List;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Lists;
@RunWith(Parameterized.class)
public class SequentialParams {
private static SystemState state;
@BeforeClass
public static void validateBeforeState() {
state = new SystemState();
Assert.assertFalse(state.one);
Assert.assertFalse(state.two);
Assert.assertFalse(state.three);
Assert.assertFalse(state.four);
}
@Parameters
public static Object buildParameters() {
Runnable reset = new Runnable() {
public void run() {
state.one = false;
state.two = false;
state.three = false;
state.four = false;
}
};
Runnable oneToTrue = new Runnable() {
public void run() {
state.one = true;
}
};
Runnable twoToTrue = new Runnable() {
public void run() {
state.two = true;
}
};
Runnable threeToTrue = new Runnable() {
public void run() {
state.three = true;
}
};
Runnable fourToTrue = new Runnable() {
public void run() {
state.four = true;
}
};
Predicate<SystemState> oneIsTrue = new Predicate<SequentialParams.SystemState>() {
public boolean apply(SystemState input) {
return input.one;
}
};
Predicate<SystemState> twoIsTrue = new Predicate<SequentialParams.SystemState>() {
public boolean apply(SystemState input) {
return input.two;
}
};
Predicate<SystemState> threeIsTrue = new Predicate<SequentialParams.SystemState>() {
public boolean apply(SystemState input) {
return input.three;
}
};
Predicate<SystemState> fourIsTrue = new Predicate<SequentialParams.SystemState>() {
public boolean apply(SystemState input) {
return input.four;
}
};
Predicate<SystemState> oneIsFalse = new Predicate<SequentialParams.SystemState>() {
public boolean apply(SystemState input) {
return !input.one;
}
};
Predicate<SystemState> twoIsFalse = new Predicate<SequentialParams.SystemState>() {
public boolean apply(SystemState input) {
return !input.two;
}
};
Predicate<SystemState> threeIsFalse = new Predicate<SequentialParams.SystemState>() {
public boolean apply(SystemState input) {
return !input.three;
}
};
Predicate<SystemState> fourIsFalse = new Predicate<SequentialParams.SystemState>() {
public boolean apply(SystemState input) {
return !input.four;
}
};
List<Object[]> params = Lists.newArrayList();
params.add(new Object[]{Predicates.and(oneIsFalse, twoIsFalse, threeIsFalse, fourIsFalse), oneToTrue, Predicates.and(oneIsTrue, twoIsFalse, threeIsFalse, fourIsFalse)});
params.add(new Object[]{Predicates.and(oneIsTrue, twoIsFalse, threeIsFalse, fourIsFalse), twoToTrue, Predicates.and(oneIsTrue, twoIsTrue, threeIsFalse, fourIsFalse)});
params.add(new Object[]{Predicates.and(oneIsTrue, twoIsTrue, threeIsFalse, fourIsFalse), threeToTrue, Predicates.and(oneIsTrue, twoIsTrue, threeIsTrue, fourIsFalse)});
params.add(new Object[]{Predicates.and(oneIsTrue, twoIsTrue, threeIsTrue, fourIsFalse), fourToTrue, Predicates.and(oneIsTrue, twoIsTrue, threeIsTrue, fourIsTrue)});
params.add(new Object[]{ Predicates.and(oneIsTrue, twoIsTrue, threeIsTrue, fourIsTrue), reset, Predicates.and(oneIsFalse, twoIsFalse, threeIsFalse, fourIsFalse)});
params.add(new Object[]{Predicates.and(oneIsFalse, twoIsFalse, threeIsFalse, fourIsFalse), threeToTrue, Predicates.and(oneIsFalse, twoIsFalse, threeIsTrue, fourIsFalse)});
params.add(new Object[]{Predicates.and(oneIsFalse, twoIsFalse, threeIsTrue, fourIsFalse), oneToTrue, Predicates.and(oneIsTrue, twoIsFalse, threeIsTrue, fourIsFalse)});
params.add(new Object[]{Predicates.and(oneIsTrue, twoIsFalse, threeIsTrue, fourIsFalse), fourToTrue, Predicates.and(oneIsTrue, twoIsFalse, threeIsTrue, fourIsTrue)});
params.add(new Object[]{Predicates.and(oneIsTrue, twoIsFalse, threeIsTrue, fourIsTrue), twoToTrue, Predicates.and(oneIsTrue, twoIsTrue, threeIsTrue, fourIsTrue)});
return params;
}
Predicate<SystemState> verifyStartState;
Runnable changeState;
Predicate<SystemState> verifyEndState;
public SequentialParams(Predicate<SystemState> pre, Runnable task, Predicate<SystemState> post) {
verifyStartState = pre;
changeState = task;
verifyEndState = post;
}
@Test
public void perform() {
Assert.assertTrue(verifyStartState.apply(state));
changeState.run();
Assert.assertTrue(verifyEndState.apply(state));
}
private static class SystemState {
public boolean one = false;
public boolean two = false;
public boolean three = false;
public boolean four = false;
}
}