2017-04-19 25 views
10

CMake ile Android'de yerel C++ kodlarım için GoogleTest'i nasıl kurarım? Android NDK, googletest ile birlikte gelir ancak talimatlar yalnızca Android.mk (here) için kullanılabilir. Android.mk gtest kurulumunu CMakeLists.txt dosyasına nasıl yüklerim? Ve bu bir kez kurulduktan sonra, test çalıştırıcısını Android Studio'nun test konfigürasyonları ile çalıştırmak mümkün mü?Android için GoogleTest NDK C++ ile CMake

cevap

1

Sadece ilk ve asıl sorularınıza bir cevap verebilirim, ancak bu bir çözüm. Android'e özgü değil; CMake ve CTest'i çalıştırabildiğiniz sürece çalışır.

GoogleTest hakkında pek bir şey bilmiyorum, ancak birkaç ay önce çok benzer bir soru olduğunu hatırlıyorum. Benim durumumda CMake'i Boost UnitTestFramework ile kullanmak istedim.

Bunun için biraz arandım, sonra a certain tutorial ile karşılaştım. Sağladıkları çözüm, test dosyalarınızın içeriğini düzenli bir ifade kullanarak ayrıştırmaktı. Tersi, oldukça özelleştirilebilir ve dosya başına birkaç birim testine izin verir. Bunu yaptım ve çok güzel çalıştı. Elbette yeni birim testleri eklediğinizde CMake'i yeniden çalıştırmanız gerekir.

Dediğim gibi, aşağıda ne yazacağım Boost UnitTestFramework için, ancak en büyük farklılıklar normal ifadelerde ve kullandığım değişken adlarında. CMake ile düzenli ifadeler kullanmıyorsanız (ben değilim), here dize işlemleri ile ilgili resmi bir belge sayfasıdır.

İşte ben ile biten CMakeLists.txt dosyadır. Bunu test/ dizininin altında bağımsız bir CMakeLists.txt dosyası olarak kullandım.

# ============================= 
# =  ADDING TESTS  = 
# ============================= 

include(CTest) 

find_package(Boost COMPONENTS unit_test_framework REQUIRED) 
include_directories(${Boost_INCLUDE_DIRS}) 

file(GLOB_RECURSE TEST_SRCS RELATIVE ${TEST_SOURCE_DIR} *.cpp) 

set(TEST_EXTRA_LIBS ${Boost_LIBRARIES} ${TEST_MAIN_LIB}) 


# Function which, given a file name and a test name, yields the 
# name of the GoogleTest test case. 
# That way, several different files can have the same test name. 
# Adapt this to GoogleTest. 
function(getTestCase testFileName testName outTestCase) 
    string(REGEX MATCH "Test([_a-zA-Z][_a-zA-Z0-9]*)" match ${testFileName}) 
    string(REGEX REPLACE ".*Test([_a-zA-Z][_a-zA-Z0-9]*).*" "\\1" testCase ${match}) 
    set(testCase Test${testCase}${testName}) 
    set(${outTestCase} ${testCase} PARENT_SCOPE) 
endfunction() 


# Function which adds all tests within a certain test file. 
function(add_all_tests_in testSrc) 
    get_filename_component(testFileName ${testSrc} NAME_WE) 

    add_executable(${testFileName} ${testSrc}) 
    target_link_libraries(${testFileName} ${TEST_EXTRA_LIBS}) 
    set_target_properties(${testFileName} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) 

    file(READ "${testSrc}" testFileContents) 

    # You should change this Regex for what you need in your case. 
    # Maybe something like: 
    # "TEST\\(*([_a-zA-Z][_a-zA-Z0-9]* *, *[_a-zA-Z][_a-zA-Z0-9]*) *\\)" 
    string(REGEX MATCHALL "DEF_TEST_CASE\\(*([_a-zA-Z][_a-zA-Z0-9]*) *\\)" unitTests ${testFileContents}) 

    foreach(match ${unitTests}) 
     # This replace will also probably need some change. 
     string(REGEX REPLACE ".*\\(*([_a-zA-Z][_a-zA-Z0-9]*) *\\).*" "\\1" testName ${match}) 
     getTestCase(${testFileName} ${testName} testCase) 
     # Actually add the test. 
     # I wanted my CTest test names to be in the form 
     # <fileName>.<testName>, but you can use any 
     # format you want. Suit yourself. 
     # 
     # Also, in order for CMake to run the tests one by one, 
     # you have to find how to invoke the test executable. 
     # In the case of Boost, the option --run_test=<Boost_Test_Name> 
     # runs only the test called <Boost_Test_Name>. There should be 
     # an equivalent option for GoogleTest, I'm sure. 
     add_test(NAME "${testFileName}.${testName}" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${testFileName} --run_test=${testCase} --catch_system_error=yes) 
    endforeach() 
endfunction() 



# Actually add all tests in all test files. 
foreach(testSrc ${TEST_SRCS}) 
    add_all_tests_in(${testSrc}) 
endforeach() 

Benim için çalışır. Tüm testler verimi, bir build/ dizin altında CMake çalışan çalıştırdıktan sonra:

$ cd test && ctest 

Test project /home/anthonyd973/Git/Git_Projects/MySweeper/build/test 
     Start 1: TestFieldMaker.makeFromFile 
1/12 Test #1: TestFieldMaker.makeFromFile ........ Passed 0.03 sec 
     Start 2: TestFieldMaker.make 
2/12 Test #2: TestFieldMaker.make ................ Passed 0.01 sec 
     Start 3: TestFieldMaker._computeFieldDims 
3/12 Test #3: TestFieldMaker._computeFieldDims ... Passed 0.01 sec 
     Start 4: TestFieldMaker._populateField 
4/12 Test #4: TestFieldMaker._populateField ...... Passed 0.00 sec 
     Start 5: TestInputField.InputField 
5/12 Test #5: TestInputField.InputField .......... Passed 0.00 sec 
     Start 6: TestCell.Cell 
6/12 Test #6: TestCell.Cell ...................... Passed 0.00 sec 
     Start 7: TestCell.initNeighbours 
7/12 Test #7: TestCell.initNeighbours ............ Passed 0.00 sec 
     Start 8: TestCell.updateNeighbours 
8/12 Test #8: TestCell.updateNeighbours .......... Passed 0.00 sec 
     Start 9: TestCell._mark 
9/12 Test #9: TestCell._mark ..................... Passed 0.00 sec 
     Start 10: TestMySweeper.MySweeper 
10/12 Test #10: TestMySweeper.MySweeper ............ Passed 0.00 sec 
     Start 11: TestField.Field 
11/12 Test #11: TestField.Field .................... Passed 0.01 sec 
     Start 12: TestField._initNeighbours 
12/12 Test #12: TestField._initNeighbours .......... Passed 0.00 sec 
100% tests passed, 0 tests failed out of 12 
Total Test time (real) = 0.10 sec 

Umarım, normal ifadeyi kullanarak :) size two problems neden olmaz.

+0

@ user740857 Bu yanıt yararlı oldu mu? Öyleyse, kabul etmek ve/veya ödül kazanmaktan çekinmeyin. Eğer değilse, neden bir başkasının size daha iyi bir cevap verme şansına sahip olduğunu kısaca açıklayabilir misiniz? –

+0

Analizleriniz için çok teşekkürler. Bilgilerinizden Android kurulumuna nasıl gidileceğini hala anlayamıyorum. – user740857

+0

@ user740857 Evet, size oldukça ayrıntılı bir çözüm sunduğum doğru. Ancak, CMake kodunu yazmadan GoogleTest'i CMake'e bağlamak için herhangi bir kolay yol olduğunu düşünmüyorum. –