32
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PythonでC言語の単体テストを書く

Posted at

C言語のテストをPythonのunittestを使って単体テストを書く方法についてです。動機は、コンパイル回数をできるだけ減らすことです。この方法を取ると、テストを書くときのコンパイルは不要になります(速度的なことや、戻り値が複雑な場合どうなるかは分かりませんが)。

まずC言語のコードは次のようなものとします。

//main.c
# include<stdio.h>
int add(int a, int b);
struct Pair {
  int l;
  int r;
};
int
main(void) {
  printf("%d + %d = %d\n", 3, 4, add(3, 4));
  return (0);
}
int add(int a, int b) {
  return a + b;
}
struct Pair  make_pair(int l, int r) {
  struct Pair p;
  p.l = l;
  p.r = r;
  return p;
}

次にgdbから呼び出すpythonコードは次のようにします。

# debug.py
import unittest

class Test(unittest.TestCase):
  def assertEqual_(self, a, expr):
    self.assertEqual(a, gdb.parse_and_eval(expr))
  def test_aaaa(self):
    self.assertEqual_(42, 'add(30, 12)')
  def test_bbb(self):
    self.assertEqual_(0, 'add(0, 0)')
  def test_ccc(self):
    p = gdb.parse_and_eval("make_pair(3, 4)")
    self.assertEqual("{l = 3, r = 4}", str(p))


gdb.execute('break main')
gdb.execute('run')
unittest.main()

C言語のコードをこのpythonコードでテストするには、次のようにします。

$ gcc -g3 main.c
$ gdb -q -x ./debug.py a.out

標準出力は次のようになります。これでPythonでC言語で書いた関数を再コンパイル無しでテストを追加、修正することが可能になります。

Reading symbols from a.out...done.
Breakpoint 1 at 0x804841c: file main.c, line 9.

Breakpoint 1, main () at main.c:9
9	  printf("%d + %d = %d\n", 3, 4, add(3, 4));
...
----------------------------------------------------------------------
Ran 3 tests in 0.003s

OK

冒頭にも書いたように、関数の戻り値が複雑な場合、特に構造体の取り扱いをもっと良くできないかと思います。C言語の方で、オブジェクトの内容を文字列に変換するような関数を用意するのが現実的かもしれません。

バージョンについて

  • Ubuntu 16.04 i386
  • gcc 5.4.0
  • GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
32
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
32
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?