如何在mocha

时间:2016-03-15 03:22:01

标签: javascript mocha

我有一个简单的两个测试例子(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?

4 个答案:

答案 0 :(得分:7)

好的,有两个问题,所以我会尝试回答这两个问题。

  1.   

    如果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);
          });
        });
      });
    });
    
  2.   

    如果我使用的是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);
    }
};