
Visual Studio 2026でC言語のテスト環境を作りたいけど、どうすればいいの?
こんな悩みを抱えている方に向けて、今回自分が実際にVisual Studio 2026でC言語の単体テスト環境を作成してみたので、その手順を画像多めで説明していきます。
結論から言うと、Visual Studio 2026でC言語のテスト環境を作りたい場合、C++でテストフレームワークを作成する必要があります。
なお、テスト環境を構築する際にいくつかフレームワークの種類があるのですが、今回は「GoogleTest」を使っています。
- Visual Studio 2026でC言語の単体テスト環境を作る方法
(フレームワーク:GoogleTest) - 実際に作成したテスト対象、テストのソースコード
本記事作成のために参照した情報
本ブログの過去記事+GitHub Copilotで確認
本記事を作成するにあたり、参考にした情報は以下です。
- 本ブログの過去記事
- Visual Studio 2026 のテスト対象プロジェクトでGitHub Copilotに相談
過去に別のフレームワーク(Microsoft標準の「Microsoft Unit Testing Framework for C++」)を使用して単体テスト環境を作成しました。

その際、他にもテストフレームワークがあり、その中でもGoogleTestの需要が多そう(?)ということが分かり、今回GoogleTestのフレーム―ワークでの環境構築にトライしてみました。
両方試してみたところ、テスト環境構築の手順自体はMicrosoft標準もGoogleTestも大差なかったため、結果的にMicrosoft標準の環境構築手順がかなり参考になりました!
具体的な手順はGitHub Copilotに相談して教えてもらっています。
GitHub Copilotに具体的な手順を聞いてみた
GitHub Copilotに「このC言語プロジェクトに単体テストを追加したい」と相談し、自分のプロジェクト構成に合わせた以下の6ステップの手順を教えてもらいました。

本ブログの過去記事と、上記手順を組み合わせて、実際に一つずつ進めていきました。
GoogleTestを用いたC言語の単体テストプロジェクト作成手順
前提:テスト用のプロジェクト構成変更イメージ
単体テストを実施するため、プロジェクト構成は今回以下のように変更しています。(プロジェクト構成は本ブログの過去記事のMSTestフレームワークを使用した時とほぼ同じです)

手順①Visual Studioでテストプロジェクトを作成する
- ソリューションエクスプローラーでソリューションノードを右クリック
- コンテキストメニューから、[追加] > [新しいプロジェクト]を選択
- 言語をC++に設定し、検索ボックスに「test」と入力
- 「ネイティブ単体テスト プロジェクト」を選択
- 任意のプロジェクト名をつけて「作成」をクリック
- 「テスト プロジェクトの構成」で今回のテスト構成に合わせた内容を選択




⇩作成されたテスト用プロジェクト(Sample-Test1)

手順② ヘッダと実装を分離する(student.h / student.c)
元々はmain.cにすべてのソースコードを書いていましたが、以下のように分離しました。
これで「student_grade_test_G」プロジェクトが、静的ライブラリとして「.lib」ファイルを出力するようになります。
- main.c:
student.hを#includeして関数を呼ぶだけ - student.h:
struct Studentと関数プロトタイプ宣言を置く - student.c:実際の処理(
calc_average,find_max_index,find_min_index,print_all)を書く
分離後のそれぞれのソースコードは以下です。
main.c
#include <stdio.h>
#include "student.h"
#define NUM_STUDENTS 5
int main(void)
{
struct Student students[NUM_STUDENTS] = {
{ "Sato", 85 },
{ "Suzuki", 92 },
{ "Takahashi", 58 },
{ "Tanaka", 74 },
{ "Watanabe", 67 }
};
print_all(students, NUM_STUDENTS);
printf("平均点: %.1f\n", calc_average(students, NUM_STUDENTS));
return 0;
}student.h
#ifndef STUDENT_H
#define STUDENT_H
#ifdef __cplusplus
extern "C" {
#endif
#define MAX_NAME 32
struct Student {
char name[MAX_NAME];
int score;
};
void print_all(const struct Student s[], int n);
double calc_average(const struct Student s[], int n);
int find_max_index(const struct Student s[], int n);
int find_min_index(const struct Student s[], int n);
#ifdef __cplusplus
}
#endif
#endif /* STUDENT_H */student.c
#include <stdio.h>
#include "student.h"
/* 全員分の成績を一覧表示する */
void print_all(const struct Student s[], int n)
{
int i;
printf("--- 成績一覧 ---\n");
printf("番号 名前 点数\n");
for (i = 0; i < n; i++) {
printf("%2d %-15s %4d\n", i + 1, s[i].name, s[i].score);
}
printf("\n");
}
/* 平均点を計算して返す(人数0のときは0.0を返す) */
double calc_average(const struct Student s[], int n)
{
int i;
double sum = 0.0;
if (n <= 0) return 0.0;
for (i = 0; i < n; i++) sum += s[i].score;
return sum / n;
}
/* 最高点の学生の添字を返す(同点なら先に見つかった方) */
int find_max_index(const struct Student s[], int n)
{
int i;
int max_i = 0;
for (i = 1; i < n; i++) {
if (s[i].score > s[max_i].score) max_i = i;
}
return max_i;
}
/* 最低点の学生の添字を返す(同点なら先に見つかった方) */
int find_min_index(const struct Student s[], int n)
{
int i;
int min_i = 0;
for (i = 1; i < n; i++) {
if (s[i].score < s[min_i].score) min_i = i;
}
return min_i;
}分離前のソースコード(main.c)全文は、以下の記事を参照ください。

手順③student_grade_test_Gを静的ライブラリ化する
- テスト対象のプロジェクト(今回だと「student_grade_test_G」)を右クリック→「プロパティ」をクリック
- 「構成プロパティ」→「全般」→「構成の種類」を Static library (.lib) に変更
出力が実行ファイル(.exe)からライブラリ(.lib)に変更されるため、コンソール画面での実行は出来なくなります。テスト環境としては意図通りのため、ご安心ください。


手順④インクルードパスを設定する
- 「Sample-Test1」プロジェクトを右クリック→「プロパティ」
- 「C/C++」→「全般」→「追加のインクルードディレクトリ」→プルダウンから「<編集…>」
- 「新しい行」→「
$(SolutionDir)student_grade_test_G(またはソースの相対パス)」を追加




手順⑤テストメソッドを記述する
- テストプロジェクトファイル(.cpp)にテストコードを記述する
今回は以下のようなテストコードを作成しました。test.cppはC++のファイルです。C++はC言語と違い、コンパイル時に関数名を内部的に変換する仕組み(名前修飾)を持っているため、C言語の関数(student.c側)をそのまま宣言しただけだと、C++側とC言語側で関数名の解釈がずれてしまい、ビルド時にリンクエラーになってしまいます。
extern "C" { ... }で囲むことで、「この中の関数はC言語のルールでコンパイルされたものだよ」とコンパイラに伝え、正しくリンクできるようにしています。
test.cpp
#include "pch.h"
#include <gtest/gtest.h>
#include <string>
extern "C" {
#include "student.h"
}
TEST(CalcAverage, Normal) {
struct Student s[] = { {"A",10}, {"B",20}, {"C",30} };
EXPECT_DOUBLE_EQ(calc_average(s, 3), 20.0);
}
TEST(CalcAverage, ZeroCount) {
EXPECT_DOUBLE_EQ(calc_average(NULL, 0), 0.0);
}
TEST(FindMaxMinIndex, Basic) {
struct Student s[] = { {"A",10}, {"B",50}, {"C",40} };
EXPECT_EQ(find_max_index(s, 3), 1);
EXPECT_EQ(find_min_index(s, 3), 0);
}
TEST(PrintAll, ProducesOutput) {
struct Student s[] = { {"A",1}, {"B",2} };
testing::internal::CaptureStdout();
print_all(s, 2);
std::string out = testing::internal::GetCapturedStdout();
EXPECT_NE(out.find("--- 成績一覧 ---"), std::string::npos);
}手順⑥ ビルドしてテストを実行する
Ctrl+Shift+Bでソリューション全体をビルドする- エラーがなければ、「テスト」→「テストエクスプローラー」→「ビュー内のすべてのテストを実行」



まとめ
MSTestでテスト環境を構築した時の経験を生かして、比較的簡単にGoogleTestの単体テスト環境を構築することができました。
同じように単体テスト環境の構築を検討している方の参考になれば嬉しいです。
最後まで読んでいただき、ありがとうございました。






コメント