Saya baru-baru ini dijual menggunakan CMake untuk menyusun proyek C ++ saya, dan sekarang ingin mulai menulis beberapa pengujian unit untuk kode saya. Saya telah memutuskan untuk menggunakan utilitas Google Test untuk membantu hal ini, tetapi memerlukan bantuan untuk memulai.
Sepanjang hari saya telah membaca berbagai panduan dan contoh termasuk Primer , pengenalan di IBM dan beberapa pertanyaan tentang SO (di sini dan di sini ) serta sumber-sumber lain yang saya lupa. Saya menyadari ada banyak hal di luar sana tetapi entah bagaimana saya masih mengalami kesulitan.
Saat ini saya mencoba menerapkan pengujian paling dasar, untuk mengonfirmasi bahwa saya telah mengumpulkan / menginstal hak gtest dan tidak berfungsi. Satu-satunya file sumber (testgtest.cpp) diambil hampir persis dari jawaban sebelumnya ini :
#include <iostream>
#include "gtest/gtest.h"
TEST(sample_test_case, sample_test)
{
EXPECT_EQ(1, 1);
}
dan CMakeLists.txt saya yang terkait adalah sebagai berikut:
cmake_minimum_required(VERSION 2.6)
project(basic_test)
# Setup testing
enable_testing()
find_package(GTest REQUIRED)
include_directories(${GTEST_INCLUDE_DIR})
# Add test cpp file
add_executable(runUnitTests
testgtest.cpp
)
# Link test executable against gtest & gtest_main
target_link_libraries(runUnitTests ${GTEST_LIBRARY_DEBUG} ${GTEST_MAIN_LIBRARY_DEBUG})
add_test(
NAME runUnitTests
COMMAND runUnitTests
)
Perhatikan bahwa saya telah memilih untuk menautkan ke gtest_main daripada memberikan yang utama di akhir file cpp karena saya yakin ini akan memungkinkan saya untuk meningkatkan pengujian dengan lebih mudah ke beberapa file.
Saat membangun file .sln yang dihasilkan (dalam Visual C ++ 2010 Express) sayangnya saya mendapatkan daftar panjang kesalahan formulir
2>msvcprtd.lib(MSVCP100D.dll) : error LNK2005: "public: virtual __thiscall std::basic_iostream<char,struct std::char_traits<char> >::~basic_iostream<char,struct std::char_traits<char> >(void)" (??1?$basic_iostream@DU?$char_traits@D@std@@@std@@UAE@XZ) already defined in gtestd.lib(gtest-all.obj)
yang menurut saya berarti saya tidak berhasil menautkan ke pustaka paling besar. Saya telah memastikan bahwa saat menautkan ke pustaka debug, saya kemudian mencoba membangun dalam mode debug.
EDIT
Setelah melakukan penggalian lagi, saya pikir masalah saya ada hubungannya dengan jenis perpustakaan yang saya bangun. Saat membangun gtest dengan CMake, jika BUILD_SHARED_LIBS
tidak dicentang, dan saya menautkan program saya ke file .lib ini, saya mendapatkan kesalahan yang disebutkan di atas. Namun, jika BUILD_SHARED_LIBS
dicentang maka saya menghasilkan satu set file .lib dan .dll. Ketika sekarang menautkan file .lib ini, program mengkompilasi, tetapi ketika dijalankan mengeluh bahwa ia tidak dapat menemukan gtest.dll.
Apa perbedaan antara a SHARED
dan a not SHARED
library, dan jika saya memilih tidak dibagikan, mengapa tidak berfungsi? Apakah ada opsi di CMakeLists.txt untuk proyek saya yang saya lewatkan?
sumber
ExternalProject_Add
daripadaadd_subdirectory
. Lihat jawaban ini untuk detailnya.enable_testing()
dilakukannya?Jawaban:
Solusinya melibatkan penempatan direktori sumber paling gt sebagai subdirektori proyek Anda. Saya telah menyertakan CMakeLists.txt yang berfungsi di bawah ini jika berguna bagi siapa pun.
sumber
pthread
ke pustaka tertaut, mengubah baris kedua terakhir menjaditarget_link_libraries(runUnitTests gtest gtest_main pthread)
make test
untuk menjalankan pengujian, atau menjalankanctest
dari direktori build. Jalankanctest -V
untuk melihat keluaran pengujian google sertactest
keluarannya.Berikut adalah contoh kerja lengkap yang baru saja saya uji. Ini mengunduh langsung dari web, baik tarball tetap, atau direktori subversi terbaru.
sumber
https://github.com/google/googletest/archive/release-1.8.0.zip
GIT_REPOSITORY https://github.com/google/googletest.git GIT_TAG release-1.8.1
sebagai pengganti URLhttps://github.com/google/googletest/archive/release-1.10.0.zip
Anda bisa mendapatkan yang terbaik dari kedua dunia. Hal ini dapat digunakan
ExternalProject
untuk mendownload sumber gtest dan kemudian digunakanadd_subdirectory()
untuk menambahkannya ke build Anda. Ini memiliki keuntungan sebagai berikut:Digunakan dengan cara biasa, ExternalProject tidak akan mengunduh dan membongkar pada waktu konfigurasi (yaitu ketika CMake dijalankan), tetapi Anda bisa melakukannya hanya dengan sedikit kerja. Saya telah menulis posting blog tentang cara melakukan ini yang juga mencakup implementasi umum yang berfungsi untuk proyek eksternal apa pun yang menggunakan CMake sebagai sistem build-nya, bukan hanya gtest. Anda dapat menemukannya di sini:
Pembaruan: Pendekatan ini sekarang juga menjadi bagian dari dokumentasi googletest .
sumber
Kemungkinan besar, perbedaan opsi compiler antara biner pengujian Anda dan pustaka Google Test adalah penyebab kesalahan tersebut. Itulah mengapa disarankan untuk membawa Google Test dalam bentuk sumber dan membuatnya bersama dengan pengujian Anda. Sangat mudah dilakukan di CMake. Anda baru saja memanggil
ADD_SUBDIRECTORY
dengan jalur ke root paling gt dan kemudian Anda dapat menggunakan target perpustakaan umum (gtest
dangtest_main
) yang ditentukan di sana. Ada lebih banyak informasi latar belakang di utas CMake ini di grup googletestframework.[Sunting]
BUILD_SHARED_LIBS
Opsi ini hanya efektif pada Windows untuk saat ini. Ini menentukan jenis pustaka yang Anda inginkan untuk dibuat oleh CMake. Jika Anda menyetelnya keON
, CMake akan membuatnya sebagai DLL, bukan sebagai lib statis. Dalam hal ini Anda harus membangun pengujian Anda dengan -DGTEST_LINKED_AS_SHARED_LIBRARY = 1 dan menyalin file DLL yang dihasilkan oleh CMake ke direktori dengan biner pengujian Anda (CMake menempatkannya di direktori output terpisah secara default). Kecuali gtest di lib statis tidak berfungsi untuk Anda, lebih mudah untuk tidak menyetel opsi itu.sumber
Itu karena Anda harus menambahkan -DGTEST_LINKED_AS_SHARED_LIBRARY = 1 ke definisi kompiler dalam proyek Anda jika Anda ingin menggunakan gtest sebagai pustaka bersama.
Anda juga dapat menggunakan pustaka statis, asalkan Anda mengompilasinya dengan opsi gtest_force_shared_crt untuk menghilangkan kesalahan yang Anda lihat.
Saya suka perpustakaan tetapi menambahkannya ke proyek benar-benar menyakitkan. Dan Anda tidak memiliki kesempatan untuk melakukannya dengan benar kecuali Anda menggali (dan meretas) ke dalam file cmake paling bagus. Malu. Secara khusus saya tidak suka ide menambahkan gtest sebagai sumber. :)
sumber
OP menggunakan Windows, dan cara yang lebih mudah untuk menggunakan GTest saat ini adalah dengan vcpkg + cmake.
Instal vcpkg sesuai https://github.com/microsoft/vcpkg , dan pastikan Anda dapat menjalankan
vcpkg
dari baris cmd. Catat folder instalasi vcpkg, mis.C:\bin\programs\vcpkg
.Instal gtest menggunakan
vcpkg install gtest
: ini akan mengunduh, mengkompilasi, dan menginstal GTest.Gunakan CmakeLists.txt seperti di bawah ini: perhatikan kita dapat menggunakan target daripada menyertakan folder.
Jalankan cmake dengan: (edit folder vcpkg jika perlu, dan pastikan jalur ke file toolchain vcpkg.cmake sudah benar)
cmake -B build -DCMAKE_TOOLCHAIN_FILE=C:\bin\programs\vcpkg\scripts\buildsystems\vcpkg.cmake
dan membangun menggunakan
cmake --build build
seperti biasa. Perhatikan bahwa, vcpkg juga akan menyalin gtest (d) .dll / gtest (d) _main.dll yang diperlukan dari folder instal ke folder Debug / Rilis.Uji dengan
cd build & ctest
.sumber
Solusi Anda dan VladLosevs mungkin lebih baik daripada solusi saya. Namun, jika Anda menginginkan solusi kekerasan, coba ini:
sumber
CMakeLists.txt paling sederhana yang saya saring dari jawaban di utas ini dan beberapa trial and error adalah:
Gtest seharusnya sudah diinstal di sistem Anda.
sumber
Sama seperti pembaruan untuk komentar @ Patricia dalam jawaban yang diterima dan komentar @ Fraser untuk pertanyaan asli, jika Anda memiliki akses ke CMake 3.11+, Anda dapat menggunakan fungsi FetchContent CMake .
Halaman FetchContent CMake menggunakan googletest sebagai contoh!
Saya telah memberikan sedikit modifikasi dari jawaban yang diterima:
Anda dapat menggunakan
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES
properti target dari target gtest dan gtest_main seperti yang ditetapkan di skrip CMakeLists.txt pengujian google .sumber
target_include_directories
dan menggunakanFetchContent_MakeAvailable(googletest)
sebagai gantinya. Ini akan mengisi konten dan menambahkannya ke build utama. CMake FetchContent - info lebih lanjutSaya memutuskan untuk menyatukan sesuatu yang generik dengan sangat cepat yang menunjukkan cara yang berbeda untuk melakukannya daripada jawaban yang diposting sebelumnya, dengan harapan itu dapat membantu seseorang. Berikut ini bekerja untuk saya di Mac saya. Pertama saya menjalankan perintah pengaturan untuk gtests. Saya baru saja menggunakan skrip yang saya temukan untuk mengatur semuanya.
Selanjutnya, saya membuat struktur folder sederhana dan menulis beberapa kelas cepat
Saya membuat CMakeLists.txt tingkat atas untuk folder utils, dan CMakeLists.txt untuk folder tes
Ini adalah CMakeLists.txt di folder tes
Kemudian yang tersisa hanyalah menulis contoh gtest dan gtest main
sample gtest
sample gtest main
Saya kemudian dapat mengkompilasi dan menjalankan gtests dengan perintah berikut dari folder utils
sumber