【问题标题】:Problems with test cases locally in CC中本地测试用例的问题
【发布时间】:2020-05-04 21:54:40
【问题描述】:

你好,我的任务是编写测试,检查扫雷板(选择重播选项后)是否与前一个不同。

首先我写了主函数the replay

之后,我在本地对其进行了测试,如果它可以正常工作,并且每场比赛,每个棋盘都不同。没有问题。 所以我开始写测试用例,现在我在这里。

TEST replay_board() {
    Game *game = create_game();
    Board *board = create_board(9, 9, 9);
    game->board = board;
    int k = 0;
    printf("\n");
    char mine_list[100];
    for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9; j++) {
            if (game->board->tiles[i][j]->is_mine == true) {
                mine_list[k] = '1';
                printf("1");
            } else {
                mine_list[k] = '0';
                printf("0");
            }

            k++;
        }
    }
    printf("\n");
    mine_list[k] = '\0';

    replay_game(replay, game);

    char mine_list2[100];
    k = 0;

    for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9; j++) {
            if (game->board->tiles[i][j]->is_mine == true) {
                mine_list2[k] = '1';
                printf("1");
            } else {
                mine_list2[k] = '0';
                printf("0");
            }
            k++;
        }
    }
    printf("\n");
    mine_list2[k] = '\0';
    int same = 0;

    if (strcmp(mine_list, mine_list2) != 0) {
        same = 0;
    } else {
        same = 1;
    }
    ASSERT_EQ(same, 0);
    PASS();
    destroy_game(game);
}

在每次测试中,它都写到旧公猪与前一头相同,但在本地我可以看到它们不一样。

我不知道比较两个字符串是否理想,但这是从结构比较它们的最简单方法

回放功能

void replay_game(char* replay, Game* game) {
    while (strcmp(replay, "yes") != 0 && strcmp(replay, "no") != 0 ) {
        scanf("%s", replay);
        if (strcmp(replay, "yes") != 0 || strcmp(replay, "no") != 0) {
            printf("invalid value\n");
        }
    }
    if (strcmp(replay, "yes") == 0) {
        destroy_board(game->board);
        game->game_state = PLAYING;
        game->board = create_board(9, 9, 9);
        game->player->score = 0;
    }
}

create_board 函数

int generate_random_coordinates(int upper_range) {
    return rand() % upper_range;
}

/**
 * Generates random coordinates to row and column according to mine count value
 * Randomly sets mines to the Board pointer
 */
void set_mines_randomly(Board *board) {
    assert(board != NULL);

    int board_mine_count = 0;
    srand(time(NULL));
    while (board_mine_count != board->mine_count) {
        int random_row = generate_random_coordinates(board->row_count);
        int random_column = generate_random_coordinates(board->column_count);

        if (board->tiles[random_row][random_column]->is_mine == false) {

            board->tiles[random_row][random_column]->is_mine = true;
            board_mine_count++;
        }
    }
}

Board *create_board(int row_count, int column_count, int mine_count) {
    Board *board = (Board *) calloc(1, sizeof(Board));
    board->row_count = row_count;
    board->column_count = column_count;
    board->mine_count = mine_count;

    for (int row = 0; row < board->row_count; row++) {
        for (int column = 0; column < board->column_count; column++) {
            board->tiles[row][column] = (Tile *) calloc(1, sizeof(Tile));
            board->tiles[row][column]->tile_state = CLOSED;
            board->tiles[row][column]->is_mine = false;
        }
    }
    set_mines_randomly(board);
    set_tile_values(board);
    return board;
}

主要

#include <stdlib.h>
#include <string.h>
#include "game.h"
#include "user_interface.h"
#include "board.h"

int main() {
    char replay[] = "yes";
    Game *game = create_game();
    Board *board = create_board(9, 9, 9);
    game->board = board;
    read_player_name(game);

    // impleting the replay function
    while(strcmp(replay, "yes") == 0) {
        play_game(game);
        printf("Chcel by si znova zahrat? (yes/no)\n");
        scanf("%3s", replay);
        printf("\n");



        // new part
        char mine_list[100];
        int k = 0;

        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                if (game->board->tiles[i][j]->is_mine == true) {
                    mine_list[k] = '1';
                    //printf("1");
                } else {
                    mine_list[k] = '0';
                    //printf("0");
                }
                k++;
            }
        }
        mine_list[k] = '\0';

        replay_game(replay, game);

        char mine_list2[100];
        k = 0;

        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                if (game->board->tiles[i][j]->is_mine == true) {
                    mine_list2[k] = '1';
                    //printf("1");
                } else {
                    mine_list2[k] = '0';
                    //printf("0");
                }
                k++;
            }
        }
        mine_list2[k] = '\0';        
        printf("%s\n", mine_list);
        printf("%s\n", mine_list2);

        // new part ending heree

    }
    destroy_game(game);
    exit(EXIT_SUCCESS);
}

在输掉比赛后跑主线 输出

   1 2 3 4 5 6 7 8 9 
1  1 1 0 0 0 0 0 0 0 
2  X 1 0 1 1 1 0 0 0 
3  - 1 0 1 X 1 0 0 0 
4  - 1 1 1 1 1 1 1 1 
5  - X 1 0 0 0 1 X - 
6  - - 2 1 1 1 2 - - 
7  - - X - - X - - - 
8  - X - - X - - - - 
9  - - - - - - X - - 

Ľutujem tom. Riešenie je nesprávne!
Vaše skóre je: 13
Chcel by si znova zahrat? (yes/no)
yes 

播放 2 分钟后

   1 2 3 4 5 6 7 8 9 
1  0 0 0 0 0 1 - 1 0 
2  0 0 0 0 1 3 X 2 0 
3  0 0 0 0 1 X X 3 1 
4  1 1 0 0 1 2 2 2 X 
5  X 1 0 0 0 0 0 1 - 
6  - 2 1 2 2 3 2 1 - 
7  - - X - X X X - - 
8  - - - - - - - 1 - 
9  - - - - - - - - - 

Ľutujem tom. Riešenie je nesprávne!
Vaše skóre je: 19
Chcel by si znova zahrat? (yes/no)

测试结果失败:

* Suite test_board:
......
000000000000001100000010001000100000000000001000100000100010000000000000000000000
000000000000001100000010001000100000000000001000100000100010000000000000000000000
F
FAIL replay_board: same != 0 (tests/test_board.c:125)

game.h

typedef enum  {
    FAILED,
    PLAYING,
    SOLVED,
} GameState;

typedef struct {
    Board *board;          /* Struct of the play field */
    Player *player;        /* Struct of user who is playing the Game */
    GameState game_state;  /* Enum for status of the Game */
} Game;

* create_game()*

Game *create_game() {
    Game *game = (Game *) calloc(1, sizeof(Game));
    Player *player = (Player *) calloc(1, sizeof(Player));
    game->player = player;
    game->player->score = 1;
    game->game_state = PLAYING;
    return game;
}

使用 printf 更新主目录后的新输出

   1 2 3 4 5 6 7 8 9 
1  - 1 0 0 0 0 0 0 0 
2  X 1 0 0 0 0 1 1 1 
3  - 1 0 0 0 0 1 X - 
4  - 1 1 0 0 1 2 - - 
5  - X 2 1 1 1 X - X 
6  1 1 2 X 1 1 2 X X 
7  0 0 1 1 1 0 1 3 X 
8  0 0 0 0 0 0 0 1 1 
9  0 0 0 0 0 0 0 0 0 

Ľutujem asd. Riešenie je nesprávne!
Vaše skóre je: 17
Chcel by si znova zahrat? (yes/no)
yes

000000000100000000000000010000000000010000101000100011000000001000000000000000000
000000001100000000000000000000100011000000000000000010010000000000001000000010000

   1 2 3 4 5 6 7 8 9 
1  - - - - - - - - - 
2  - - - - - - - - - 
3  - - - - - - - - - 
4  - - - - - - - - - 
5  - - - - - - - - - 
6  - - - - - - - - - 
7  - - - - - - - - - 
8  - - - - - - - - - 
9  - - - - - - - - - 



【问题讨论】:

  • 我知道创建一个二维板或某种结构来表示板似乎是合乎逻辑的。但是如果你真的使用一个简单的数组,你可以只做一个 memcmp。在这种情况下,它甚至可以是一个位数组。如果你对这些位进行零填充,你基本上会得到一个代表一块板的 100 位数字。这仅适合 13 个字节。想象一下,“打开”的图块以类似的位数组表示。您可以使用按位与运算来检查玩家是否打开了矿井。我认为这将是一个很好的练习。
  • 您能发布一个可以编译的最小完整示例吗?当前列出的代码不完整。什么是Gamecreate_game() 等。

标签: c testing compare structure assert


【解决方案1】:

问题来了:

char* mine_list[100];

您将mine_list 定义为char * 的数组,而不是char 的数组。无论您在哪里使用,您的编译器都应该给您一些警告。将其更改为char 的数组:

char mine_list[100];

【讨论】:

    【解决方案2】:

    您是否检查过replay_game("yes", game); 确实改变了游戏规则?

    无论哪种方式,都有一种更简单、更正确的方法来做到这一点。 分配一个新的board*指针,使用memcpy将board的内容复制到新分配的内存中,然后调用replay_game。假设这实际上改变了board 变量,您现在可以简单地比较一个嵌套循环中的两个板。

    【讨论】:

    • 我更新了我的描述,是的,它实际上改变了游戏,因为它删除了旧结构并创建了一个新结构,而且还有随机因素,所以它不能和以前的一样跨度>
    • 尝试打印一些值作为健全性检查。另请注意,当您只使用 82 时,您将字符串初始化为 100 个字符。我还建议使用 strncmp,因为长度是预先知道的。这可能不是问题,但我们不要冒险。
    • 更新了测试用例也包含了main函数
    • 我在发布之前打印了之前的地雷字符串和第二个地雷字符串,它们完全相同(当然在测试用例中)
    • 尝试打印更多变量,例如矿井列表,这将帮助您了解一切失败的地方。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多