代码之家  ›  专栏  ›  技术社区  ›  JohnDoe

测试随机失败

  •  0
  • JohnDoe  · 技术社区  · 7 年前

    我正在编写棋盘游戏,我需要以下功能:玩家掷两个骰子,如果他掷双倍(两个骰子上的数字相同),他将再次掷骰,如果他再次掷双倍,他将入狱。

    在我的 Game 同学们看起来是这样的

    void logic::Game::rollTheDice() {
        m_throwsInCurrentTurn++; 
        int firstThrow = m_firstDice.roll();
        int secondThrow = m_secondDice.roll();
        m_totalRollResult += firstThrow + secondThrow;
        if (firstThrow == secondThrow) m_doublesInCurrentTurn++;
    }
    
    std::string logic::Game::checkForDoubles() {
        std::string message;
            if (m_doublesInCurrentTurn == 0 && m_throwsInCurrentTurn == 1) {
                m_canThrow = false;
                m_canMove = true;           
            }
    
            if (m_doublesInCurrentTurn == 1 && m_throwsInCurrentTurn == 1) {
                message = "Doubles! Roll again.";           
                m_canThrow = true;
                m_canMove = false;
            }
    
            if (m_doublesInCurrentTurn == 1 && m_throwsInCurrentTurn == 2) {            
                m_canThrow = false;
                m_canMove = true;
            }
    
            if (m_doublesInCurrentTurn == 2 && m_throwsInCurrentTurn == 2) {
                message = "Doubles again! You are going to jail.";
                m_canThrow = false;
                m_canMove = false;
                getActivePlayer().lockInJail();
            }
            return message;
        }
    
    void logic::Game::setInMotion(unsigned number) {
        m_players[m_activePlayer].startMoving(); 
        m_players[m_activePlayer].incrementPosition(number);
    }
    

    m_canThrow 基本上启用或禁用单击“掷骰子”按钮的功能, m_canMove 决定玩家令牌是否可以开始移动, m_players[m_activePlayer] std::vector<Player> , startMoving() 这样做,

    void logic::Player::startMoving() {
        m_isMoving = true;
    } 
    

    代币移动所需,因此此处不相关。

    来自的最后一个函数 游戏 我要告诉你的是 reset() ,主要用于测试目的

    void logic::Game::reset() {
        m_throwsInCurrentTurn = 0;
        m_doublesInCurrentTurn = 0;
        m_totalRollResult = 0;
    }
    

    现在,最终的单元测试有时会出错。有时,我指的是完全随机的,比如10-20次中的1次。

    //first throw is double, second throw is not
    TEST_F(GameTestSuite, shouldFinishAfterSecondRollAndMove) {
        auto game = m_sut.get();
    
        do {
            if (game.getThrowsInCurrentTurn() == 2) game.reset();
            game.rollTheDice();
            game.checkForDoubles();
            if (game.getThrowsInCurrentTurn() == 1 && game.getDoublesInCurrentTurn() == 1) {
                ASSERT_EQ(game.canThrow(), true);
                ASSERT_EQ(game.canMove(), false);           
            }
        } while (game.getThrowsInCurrentTurn() != 2 && game.getDoublesInCurrentTurn() != 1);
    
        ASSERT_EQ(game.canThrow(), false);
        ASSERT_EQ(game.canMove(), true);
    
        game.setInMotion(game.getTotalRollResult());
    
        ASSERT_EQ(game.getActivePlayer().isMoving(), true);
        ASSERT_EQ(game.getActivePlayer().getPosition(), game.getTotalRollResult());
    }
    

    这一行没错, ASSERT_EQ(game.canThrow(), false); 有时是平等的 true 之后 do-while 应该结束一次的循环 m\u悬臂 设置为 false

    1 回复  |  直到 7 年前
        1
  •  0
  •   Francis Cugler    7 年前

    不应:

    } while (game.getThrowsInCurrentTurn() != 2 && game.getDoublesInCurrentTurn() != 1);
    

    } while (game.getThrowsInCurrentTurn() != 2 && game.getDoublesInCurrentTurn() <= 1);
    

    您希望最多允许两圈,但允许0或1圈。