【问题标题】:Jasmine testing, seemingly unrelated tests are interfering with other testsJasmine 测试,看似无关的测试正在干扰其他测试
【发布时间】:2016-02-10 09:29:40
【问题描述】:

请查找 // **** 这是有问题的代码,位于此行 **** 注释下方。

在我用 cmets 划分的代码中有两个主要的描述函数。在第一个 describe("Start up defaults") 如果我取出最后一个测试它('gameStarted and gameOver should be false'),第二个 describe("player presses start") 中的所有测试都通过(我指的是测试元素是否具有“灰色”类)。

但如果我像现在一样包含最后一个测试,那么第二个 describe("player presses start") 中关于元素是否具有“灰色”类的所有测试都失败了。

如果我注释掉最后一个测试('gameStarted 和 gameOver 应该是 false'),那么其他测试会再次通过。将其注释掉后,如果我将测试复制并粘贴到它上面('玩家 2 应该是计算机')(以确保它不是语法问题),其他测试再次失败!我已经黔驴技穷了。我可以在该描述块中放入多少 it() 是有限制的。

重申一下,spyClickEvent 测试总是通过。 开始按钮启动游戏,除重启按钮外的所有选项都灰显。

整个项目在 Github 上:https://github.com/Spekachu/Tic-Tac-Toe

您可以在 codepen http://codepen.io/Spekachu/pen/adKprJ?editors=0010 上查看 Javascript 但那里没有茉莉花。 布尔值都被初始化为我期望它们在这些测试中的样子。

一些javascript代码贴在底部,比如按下开始按钮时的开始功能。

describe('Tic Tac Toe', function(){
  jasmine.getFixtures().fixturesPath = '/';
  var spyClickEvent; // will detect all button clicks and game board clicks
  beforeEach(function(){
    loadFixtures('index.html');
  });
  describe("Game Board", function(){
    it ('should have id "game-board"', function(){
      expect( $('#game-board') ).toExist();
    });
    describe ('children', function(){
      it ('there should be 5 children', function(){
        expect( $('#game-board').children().length ).toEqual(5);
      });
      describe ('#name-plate', function(){
        it ('exists', function(){
          expect( $('#name-plate') ).toExist();
        });
      });
      describe ('#result-ribbon', function(){
        it ('exists', function(){
          expect( $('#result-ribbon') ).toExist();
        });
      });
      describe ('#play-wrapper', function(){
        it ('exists', function(){
          expect( $('#play-wrapper') ).toExist();
        });
        describe ('has #play-area, where the pieces get played', function(){
          it("exists", function(){
            expect( $('#play-area') ).toExist();
          });
          describe('slots', function(){
            it('should have 9 slots', function(){
              $('#play-area').html('');
              initVars();
              expect($('#play-area').children().length).toEqual(9);
            });
            it('each slot has an X and O background inset', function(){
              $('#play-area').children().each(function(slot, val){
                expect(val).toContainElement('p.shadow.o'); expect(val).toContainElement('p.shadow.x');
              });
            });
            it('should have no played pieces at start', function(){
              expect(gamePrintOut).toEqual(" | | \n | | \n | | ");
              expect(playedPieces.length).toEqual(0);
              expect(availSlots.length).toEqual(9);
            });
            // GAME PLAY
          });
        });
      });
      describe ('#options-wrapper', function(){
        it ('exists', function(){
          expect( $('#options-wrapper') ).toExist();
        });

 // *******************************************************************
 // !!!!!! THIS IS THE CODE IN QUESTION, BELOW this line !!!!!!!!!!!!!!

        describe('Start up defaults', function(){
          it('Restart should be greyed out while the rest are red and clickable', function(){
            expect($('#restart')).toHaveClass('greyed');
            expect($('#start')).not.toHaveClass('greyed');
            expect($('.piece-switch')).not.toHaveClass('greyed');
            expect($('.choice-switch')).not.toHaveClass('greyed');
            expect($('.order-switch')).not.toHaveClass('greyed');
          });
          it('player should be x, and be going first', function(){
            expect(userIsX).toBe(true);
            expect(userFirst).toBe(true);
            expect(usersTurn).toBe(true);
          });
          it('player 2 should be Computer', function(){
            expect(player2IsComp).toBe(true);
          });
          it('player 2 should be Computer', function(){
            expect(player2IsComp).toBe(true);
          });
          it('gameStarted and gameOver should be false', function(){
            expect(gameStarted).toBe(false);
            expect(gameOver).toBe(false);
          });
        });

        describe ('Player presses start', function(){
          it ('should grey out options and itself and make Restart red and clickable', function(){
            spyClickEvent = spyOnEvent('#start', 'click');
            $('#start').trigger( "click" );
            expect('click').toHaveBeenTriggeredOn('#start');
            expect(spyClickEvent).toHaveBeenTriggered();

            expect($('#restart')).not.toHaveClass('greyed');
            expect($('#start')).toHaveClass('greyed');
            expect($('.piece-switch')).toHaveClass('greyed');
            expect($('.choice-switch')).toHaveClass('greyed');
            expect($('.order-switch')).toHaveClass('greyed');
          });
        });

 // ^^^^^^^^ THIS IS THE CODE IN QUESTION, ABOVE this line ^^^^^^^^^^^^^^^^
 // *******************************************************************

      });
      describe ('#made-by', function(){
        it ('exists', function(){
          expect( $('#made-by') ).toExist();
        });
      });
    });
  });
});

选择 JAVASCRIPT 代码

var usersTurn = true;
var userFirst = true;
var gameStarted = false;
var gameOver = false;
var userIsX = true;
var p2CanWin = false;
var userCanWin = false;
var player2IsComp = true;

var xSymbol = '&#x02A2F';
var isAndroid = /(android)/i.test(navigator.userAgent);
if (isAndroid) {
  xSymbol = 'x';
}
var slots = ('<div class="slot"> <p class="shadow x">'+ xSymbol +'</p> <p class="shadow o">O</p> </div> ').repeat(9);

function initVars() {
  playArea.html(slots);
  winningSlots = [];
  printGame();
}
function startGame() {
  $('#restart').removeClass('greyed');
  $('#start').addClass('greyed');
  $('.switch-container .switch').addClass('greyed');
  gameStarted = true;
  gameOver = false;
  if (!userFirst)
    computerGo();
  updateSizes();
}

更新

如果我离开最后一个测试它('gameStarted 和 gameOver 应该是假'){...});注释掉所以一切都过去了--> 然后,如果我在相同的描述(“播放器按下开始”)中插入此代码,然后在它(“应该灰色选项...”){...}

      it ("this should pass", function(){
        expect(1).toEqual(1);
      });

一切都会过去。但是如果我在它之前剪切并粘贴它(“应该将所有其他选项变灰...”),那么它们会再次失败!

(我也知道我应该先从测试开始这个项目,不幸的是我后来才开始)

【问题讨论】:

  • 您能否发布这些变量/方法的代码:gameStarteduserIsXinitVars() 等?
  • 是的!我添加了包含所有 js 的 codepen 链接。 gameStarted 和其他布尔值在我的 .js 中初始化为我期望它们在这些测试中的样子。 initVars() 只是为游戏板添加了 9 个 div 的 html。所有其他变量在声明时都会初始化。
  • 如果我在 spyClickEvents 之后和测试失败之前调用 startGame() 函数,它们都通过了,我没有问题。我假设 .trigger 函数会触发我的 .js 调用 startGame() 函数,但代码可能会触发“点击”。为什么在 it('should gray out options'){...} 上添加 ANYmore it() 函数会导致这些测试失败,这对我来说仍然是个谜。
  • 对 Jasmine 的错误信息持保留态度。有时它会在与您实际犯错的地方完全不同的地方报告错误。
  • 是的,尽管我现在可以继续前进,但我不明白错误是什么。无论如何,谢谢你的帮助。我想我还是习惯了 Jasmine,毕竟这是我第一次使用它。

标签: javascript unit-testing testing jasmine jasmine-jquery


【解决方案1】:

所以,我检查了您的代码,控制台日志消息在我看来,测试是在 jquery 初始化之前运行的。我不知道为什么,因为我以前没有使用过 jquery-jasmine,但是让你的 test async 应该可以解决这个问题:

describe ('Player presses start', function(){
    it ('should grey out options and itself and make Restart red and clickable', function(done){
        setTimeout(function() {
            spyClickEvent = spyOnEvent('#start', 'click');
            $('#start').trigger( "click" );
            expect('click').toHaveBeenTriggeredOn('#start');
            expect(spyClickEvent).toHaveBeenTriggered();
            expect($('#restart')).not.toHaveClass('greyed');
            expect($('#start')).toHaveClass('greyed');
            expect($('.piece-switch')).toHaveClass('greyed');
            expect($('.piece-switch')).toHaveClass('greyed');
            expect($('.choice-switch')).toHaveClass('greyed');
            expect($('.order-switch')).toHaveClass('greyed');
            done();
        }, 2000);
    });
});

【讨论】:

  • 使用超时等待某事发生很少是一个好的解决方案。这不是罕见的情况之一。
猜你喜欢
  • 2021-07-25
  • 2012-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-10
  • 2019-10-23
  • 2014-11-15
  • 2011-12-02
相关资源
最近更新 更多