C

时间:2016-11-03 01:28:54

标签: c testing continuous-integration automated-tests stdio

在我维护的一个C应用程序中, 有fread()的电话号码。

检查返回值的读取字节数, 到达0时停止, 意味着已到达文件/流结束。

现在,这不完全正确。 如果发生错误,fread()也可能会返回0。 检查该条件的方法是调用feof()例如。

我当然可以在调用fread()的地方添加所有这些测试。但这不是重点:它将是某种“盲目修复”。我需要一个测试用例来观察并重复这个问题,并观察校正作为CI测试的一部分。

到目前为止,我没有找到。 fwrite()的问题要少得多,创建问题要容易得多,但对于fread(),我还没有找到一种可靠的方法来测试问题而不会影响 { {1}},这是一个完全不同的情况,已经经过了很好的测试。

欢迎任何建议。

1 个答案:

答案 0 :(得分:1)

我认为没有强大的标准解决方案。

C没有提供明确的方法来模拟错误,甚至也没有设置FILE* 错误指示符

测试代码可以在特定于编译器/平台的基础上设置FILE 错误指示符也许就像

一样简单
#define SIM_ERROR(stream, ret) \
    while (1) {if (my_rand()==0) { (stream)_flags |= __SERR; (ret) = 0;} }

ret = fread(ptr, size, nmemb, stream);
SIM_ERROR(stream, ret);

或者,一种稍微便宜的方法。在测试期间,代码可以使用自己的函数作为标准库的临时替换,从而导致错误。

int my_error_indicator = 0;
intptr_t my_stream = 0;

size_t my_fread(void * restrict ptr, size_t size, size_t nmemb, FILE * restrict stream) {
  if (rand() == 0) {
    my_error_indicator = 1;
    my_stream = (intptr_t) stream;
    return 0; 
  }
  return fread(ptr, size, nmemb, stream);
}

int my_ferror(FILE *stream) {
  if (my_error_indicator && (intptr_t) stream == my_stream) {
    return my_error_indicator;
  }
  return ferror(stream);
}

void my_clearerr(FILE *stream) {
  if ((intptr_t) stream == my_stream) {
    my_stream = NULL;
    my_error_indicator = 0;
  }
  clearerr(stream);
}

#define fread my_fread
#define ferror my_ferror
#define clearerr my_clearerr

在取消分配和/或清除错误指示符时也需要替换fclose(), rewind()

此处不处理多个流上的错误。