我有一个简单的两个测试例子(A,B),其中B依赖于A运行。
如果我使用的是Mocha,我可以将测试B嵌套在A:
中describe.only( 'AB:', function() {
describe( 'A', function() {
it( 'A1', function() {
assert.equal( 1, 2 );
} );
describe( 'B', function() {
it( 'B1', function() {
assert.equal( 1, 1 );
} );
} );
} );
} );
但即使A失败,A和B都会运行。
这与使用嵌套有何不同?
describe.only( 'AB:', function() {
describe( 'A&B', function() {
it( 'A1', function() {
assert.equal( 1, 2 );
} );
it( 'B1', function() {
assert.equal( 1, 1 );
} );
} );
} );
如果A失败,有没有办法跳过B?
答案 0 :(得分:7)
好的,有两个问题,所以我会尝试回答这两个问题。
如果A失败,有没有办法跳过B?
通常,您应该编写不相互依赖的测试。
有时测试依赖于在能够正常运行之前具有某些设置或状态,在这种情况下,最好在before()
或beforeEach()
块中进行设置。如果这些块中的任何一个失败,则不会运行它们之后的测试。因此,当你的构建过程中你知道描述块中的所有测试都不起作用时,你可以在这些块中抛出一个错误。
describe.only('AB:', function() {
var numberUnderTest = 0;
describe('A&B', function() {
it('A1', function() {
assert.equal(1, 1 * numberUnderTest);
});
describe('B', function() {
before(function() {
if (numberUnderTest === 0) {
throw 'cannot divide by zero';
}
});
it('B1', function() {
assert.equal(1, 1 / numberUnderTest);
});
});
});
});
如果我使用的是Mocha,我可以将测试B嵌套在A
中 [...]
这与使用嵌套有何不同?
将B嵌套在描述块中允许您对B1使用不同于A1的设置,同时仍然继承A的一些设置。
describe('A', function() {
var numberUnderTest;
var anotherNumber;
beforeEach(function() {
numberUnderTest = 1;
anotherNumber = 0;
});
it('A1'), function() {
assert.equal(0, anotherNumber * numberUnderTest);
});
describe('B', function() {
before(function() {
anotherNumber = 1;
});
it('B1', function() {
assert.equal(1, anotherNumber / numberUnderTest);
});
});
});
答案 1 :(得分:4)
最简单的方法是使用mocha-steps:
describe('my smoke test', function() {
step('login', function() {
});
step('buy an item', function() {
throw new Error('failed');
});
step('check my balance', function() {
});
xstep('temporarily ignored', function() {
});
});
完整博客文章:https://watirmelon.blog/2018/07/04/bailing-with-mocha-e2e-tests/
答案 2 :(得分:0)
如果A失败,有什么方法可以跳过B?
这种模式一直很适合我:
var itCanLogin;
it('Can login', function() {
...
itCanLogin = true;
});
it('Can Logout', function(){
if(!itCanLogin) this.skip()
...
})
也可以使用assert(itCanLogin)
,但是this.skip()
不会产生堆栈跟踪和错误,从而有助于使输出更整洁-可以更容易地注意到问题的根源。
答案 3 :(得分:0)
class DPSolver
{
Activities activities_;
mutable CacheTable cacheTable_;
Activities impl(std::size_t from, std::size_t to, std::size_t money) const
{
if((from >= to) || (money == 0)){
return {};
}
const auto cache = cacheTable_(to, money);
if(!cache.empty()){
return cache;
}
for(const auto& act_i : activities_)
{
if((act_i.to <= to) && (money >= act_i.cost))
{
const auto remaining = (money - act_i.cost);
auto acts = impl(from, act_i.from, remaining);
const auto thisCost = calcCost(acts) + act_i.cost;
const auto found = cacheTable_.getCachedOptimal(act_i.to, thisCost);
if(found.size() < (acts.size()+1))
{
acts.push_back(std::move(act_i));
cacheTable_(act_i.to, thisCost) = acts;
}
}
}
return cacheTable_.getCachedOptimal(to, money);
}
public:
DPSolver(const Activities& activities) : activities_(preprocess(activities))
{}
static Activities preprocess(const Activities& activities)
{
auto sorted(activities);
// preprocessing to order by finished time "to".
std::sort(
sorted.begin(), sorted.end(),
[](const activity& al, const activity& ar)
{ return std::tie(al.to, al.from, al.cost) < std::tie(ar.to, ar.from, ar.cost); });
return sorted;
}
static std::size_t calcCost(const Activities& activities)
{
return std::accumulate(
activities.cbegin(), activities.cend(), 0,
[](int sum, const activity& a){ return sum + a.cost;});
}
Activities operator()(std::size_t from, std::size_t to, std::size_t money) const
{
// clear cache table
cacheTable_ = CacheTable();
return impl(from, to, money);
}
};