在我看來,斷言機制並不是Fortran單元測試的主要關注點。正如您在鏈接中回答的那樣,Fortran有幾個單元測試框架,例如funit和FRUIT。
不過,我認爲,主要問題是依賴關係的解決。您可能擁有一個包含許多相互依存模塊的巨大項目,並且您的測試應該涵蓋使用其他模塊的其中一個模塊。因此,您需要找到這些依賴關係並相應地構建單元測試。一切都歸結爲編譯可執行文件,斷言的優勢非常有限,因爲您無論如何都需要定義您的測試並自行進行比較。
我們正在用Waf構建我們的Fortran應用程序,它帶有一個單元testing utility itself。現在,我不知道這是否可以讓你使用,但唯一的要求是Python,它幾乎可以在任何平臺上使用。一個缺點是,測試依賴於返回代碼,而這並不容易從Fortran獲得,至少在Fortran 2008之前不能以便攜方式獲得,而Fortran 2008建議在返回代碼中提供停止代碼。所以我修改了我們項目成功的檢查。而不是檢查返回代碼,我希望測試寫一些字符串,並在輸出中檢查的是:
def summary(bld):
"""
Get the test results from last line of output::
Fortran applications can not return arbitrary return codes in
a standarized way, instead we use the last line of output to
decide the outcome of a test: It has to state "PASSED" to count
as a successful test.
Otherwise it is considered as a failed test. Non-Zero return codes
that might still happen are also considered as failures.
Display an execution summary:
def build(bld):
bld(features='cxx cxxprogram test', source='main.c', target='app')
from waflib.extras import utest_results
bld.add_post_fun(utest_results.summary)
"""
from waflib import Logs
import sys
lst = getattr(bld, 'utest_results', [])
# Check for the PASSED keyword in the last line of stdout, to
# decide on the actual success/failure of the test.
nlst = []
for (f, code, out, err) in lst:
ncode = code
if not code:
if sys.version_info[0] > 2:
lines = out.decode('ascii').splitlines()
else:
lines = out.splitlines()
if lines:
ncode = lines[-1].strip() != 'PASSED'
else:
ncode = True
nlst.append([f, ncode, out, err])
lst = nlst
此外,我按照約定增加測試中,只是一個目錄,必須提供構建腳本和與_test.f90結束該目錄中的所有文件都會被假定爲單元測試,我們將嘗試建立並運行它們:
def utests(bld, use, path='utests'):
"""
Define the unit tests from the programs found in the utests directory.
"""
from waflib import Options
for utest in bld.path.ant_glob(path + '/*_test.f90'):
nprocs = search_procs_in_file(utest.abspath())
if int(nprocs) > 0:
bld(
features = 'fc fcprogram test',
source = utest,
use = use,
ut_exec = [Options.options.mpicmd, '-n', nprocs,
utest.change_ext('').abspath()],
target = utest.change_ext(''))
else:
bld(
features = 'fc fcprogram test',
source = utest,
use = use,
target = utest.change_ext(''))
你可以找到像在Aotus library定義的單元測試。
from waflib.extras import utest_results
utest_results.utests(bld, 'aotus')
它是那麼還可以通過在夜猴運行
./waf build --target=aot_table_test
建立從單元測試僅子集,例如:其通過利用在wscript。我們的測試環境有點微薄,但我認爲這個基礎設施展會實際上相當不錯。測試可以簡單地利用項目中的所有模塊,並且可以毫不費力地進行編譯。
現在我不知道這是否適合你,但我會考慮更多關於你的測試在你的構建環境中的整合,而不是關於斷言的東西。在每個模塊中都有一個測試程序是一個好主意,然後可以從測試程序中輕鬆調用。我會試着針對你想測試的每個模塊尋找一個可執行文件,其中每個模塊當然可以包含多個測試。
感謝您的反饋意見。不幸的是Waf在這裏不是一個選項(令人沮喪的是,我沒有辦法從外部源代碼導入代碼,而不是依賴性問題)。我完全同意你關於解耦和依賴解決方案是主要挑戰的觀點 - 我尋找解決方案的原因之一是鼓勵團隊的其他成員考慮依賴關係問題;我發現在過去,單元測試是鼓勵這種做法的有效方法。看到你如何在一個並行項目上解決問題非常有趣。歡呼聲 – s8129
至少,Fortran 2008標準建議編譯器供應商在停止語句(例如停止2)中使用錯誤代碼作爲退出代碼,因此有一種準便攜式方式返回退出代碼。 –
@BálintAradi,感謝您指出,我不依賴於F2008的功能,而且上次我用不同的編譯器進行了檢查,結果無法正常工作。我會將其添加到答案中。 – haraldkl