我想制作一个类似于单元测试的框架,允许我为各个规则编写自定义测试。我希望每个测试都在它自己的文件中,即 test_R1.clp
将是规则 R1 的测试文件。每个测试都应该能够加载它自己的事实文件。我已经尝试了以下的许多变体,包括对每个文件使用不同的 defmodule。我在 CLIPS 中尝试做的事情甚至可能吗?如果是这样,还需要什么才能使这项工作正常进行?
我想通过以下方式运行我的测试:
$CLIPSDOS64.exe -f2 .\test_all.clp
对于当前示例,我得到的错误是
[EXPRNPSR3] 设置测试缺少函数声明。
我已经为每个文件使用唯一的 defmodule 进行了一次测试以正常工作(即测试框架的 UNITTEST 和 test_R1 文件的 R1)。但是,由于在加载文件时或在其他文件中定义函数时在焦点语句之间自动切换,我仍然会出错。我看过基本和高级 CLIPS 编程指南,但如果我在那里遗漏了什么,请告诉我。
其他具体问题:
- 由于某些测试可能会加载覆盖现有事实的事实,我该如何防止因重新定义现有事实而出错?我是否需要在运行每个测试之间执行
(clear)
?
测试框架.clp:
;;; File: TestingFramework.clp
(defglobal ?*tests-counter* = 0)
(defglobal ?*all-tests-passed* = TRUE)
(defglobal ?*failed-tests-counter* = 0)
(deftemplate test_to_run
(slot testid)
(slot testname)
(slot testsetupfunc)
(slot testcheckfunc))
(deffunction test-check (?test-name ?test-condition)
(if (eval ?test-condition)
then (printout t "SUCCESS: Test " ?test-name crlf)
(printout test_results_file "SUCCESS: Test " ?test-name crlf)
(return TRUE)
else (printout t "FAILURE: Test " ?test-name crlf)
(printout test_results_file "FAILURE: Test " ?test-name crlf)
(return FALSE)))
(deffunction setup_tests ()
(open "test_summary_results.txt" test_results_file "w"))
(deffunction finish_tests ()
(close test_results_file))
(deffunction add_test (?test-name ?test-setup-func ?test-check-func)
(bind ?*tests-counter* (+ 1 ?*tests-counter*))
(assert (test_to_run (testid ?*tests-counter*)
(testname ?test-name)
(testsetupfunc ?test-setup-func)
(testcheckfunc ?test-check-func))))
(deffunction run_all_tests ()
(printout t "About to run " ?*tests-counter* " test(s):" crlf)
(do-for-all-facts ((?ttr_fact test_to_run)) TRUE
(funcall (fact-slot-value ?ttr_fact testsetupfunc))
(if (funcall (fact-slot-value ?ttr_fact testcheckfunc))
then (printout t " SUCCESS" crlf)
else (printout t " FAILURE" crlf)
(bind ?*failed-tests-counter* (+ 1 ?*failed-tests-counter*))
(bind ?*all-tests-passed* FALSE)))
(if ?*all-tests-passed*
then (printout t "All " ?*tests-counter* " tests passed successfully." crlf)
else (printout t ?*failed-tests-counter* "/" ?*tests-counter* " tests failed." crlf)))
测试\test_R1.clp:
;;; File: test_R1.clp
;;; Tests for Rule 1
(deffunction R1_TEST_1_SETUP ()
(load* "FluidSystem_facts_demo.clp")
(load* "FluidSystem_rules_demo.clp")
(reset))
(deffunction R1_TEST_1 ()
(send [JacketWaterInletTempReading] put-hasValue 35.0)
(send [JacketWaterInletTempReading] put-hasValueDefined DEFINED)
(send [JacketWaterOutletTempReading] put-hasValue 37.0)
(send [JacketWaterOutletTempReading] put-hasValueDefined DEFINED)
(run)
(return (member$ [DissimilarHighTempFlowRate] (send [CounterFlowHeatExchanger] get-hasIssue))))
test_all.clp:
;;; File: test_all.clp
;;; Run tests via:
;;; CLIPSDOS64.exe -f2 .\test_all.clp
(load* "TestingFramework.clp")
(setup-tests)
;;; Test R1
(load* "tests\\test_R1.clp")
(add_test (test_to_run "R1_TEST_1" R1_TEST_1_SETUP R1_TEST_1))
(clear) ;; unsure if this is needed
;;; ... more tests to follow
(run_all_tests)
(finish_tests)
最佳答案
CLIPS 回归测试使用的框架可能会满足您的需求。您可以从 6.4 下载目录之一下载它 (clips_feature_tests_640.zip)(sourceforge.net/projects/clipsrules/files/CLIPS/6.40_Beta_3/当前测试版)。要运行测试,请在同一目录中启动 CLIPS 并执行(批处理“testall.tst”)命令。使用 CLIPS 终端应用程序,您还可以使用“clips -f testall.tst”从 shell 运行它们。执行完成后,您可以查看 Results 目录中的 *.rsl 文件以获取结果。如果出现差异,您可以使用 diff 程序将 Actual 目录中的 .out 文件的内容与 Expected 目录的内容进行比较。
框架使用批处理命令自动加载和运行测试用例。 dribble-on 命令用于捕获每个测试用例的输出并将其放置在 Actual 目录中它自己的文件中。该框架允许您运行所有测试用例(使用 testall.tst 批处理文件),或者您可以通过运行与测试关联的 .tst 批处理文件来运行任何单个测试用例。
关于testing - 使用多文件设置设计一个单元测试框架,用于在 CLIPS 中为 CLIPS 规则编写自定义测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59055140/