- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我使用 Parsec
编写了一个文件解析器图书馆。我想使用 Tasty
编写高级单元测试测试框架以确保解析器正确解析某些给定文件。
我在以下目录结构中有三个格式正确的文件:
path/to/files -+
|-> fileA
|-> fileB
|-> fileC
path/to/files
中的所有文件testCase
确保文件内容被成功解析的每个文件{-# LANGUAGE BangPatterns, FlexibleContexts #-}
module Test.MyParser
( testSuite
) where
import Control.Arrow ((&&&))
import Data.Map (Map,fromList,toList)
import System.Directory
import System.IO.Unsafe (unsafePerformIO) -- This is used for a hack
import Test.Tasty (TestTree,testGroup,withResource)
import Test.Tasty.HUnit
import Text.Parsec
-- | Determine if an Either is a Right or Left value
-- Useful for determining if a parse attempt was successful
isLeft, isRight :: Either a b -> Bool
isLeft (Left _) = True
isLeft _ = False
isRight = not . isLeft
-- | My file parser, a Parsec monad definition
myFileParser :: Parsec s u a
myFileParser = undefined -- The parser's definition is irrelivant
-- | Gets all the given files and thier contents in the specified directory
getFileContentsInDirectory :: FilePath -> IO (Map FilePath String)
getFileContentsInDirectory path = do
files <- filter isFile <$> getDirectoryContents path
sequence . fromList $ (id &&& readFile) . withPath <$> files
where
isFile = not . all (=='.')
withPath file = if last path /= '/'
then concat [path,"/",file]
else concat [path, file]
-- | Reads in all files in a directory and ensures that they correctly parse
-- NOTE: Library hack :(
-- On success, no file names will be displayed.
-- On the first failure, no subsequent files will have parsing attempt tried
-- and the file path for the failed file will be displayed.
testSuite :: TestTree
testSuite = testGroup "Files that should successfully be parsed" [withResource validContents release validateFiles]
where
validContents = getFileContentsInDirectory "path/to/files"
release = const $ pure ()
parse' :: (FilePath,String) -> Either ParseError a
parse' (path,content) = parse myFileParser path content
success :: (FilePath,String) -> Assertion
success (path,content) = assertBool path . isRight $ parse' (path,content)
validateFiles :: IO (Map FilePath String) -> TestTree
validateFiles !filesIO = testGroup "Valid files" [testCase "Unexpected parse errors" fileTree]
where
fileTree :: IO () --also an Assertion
fileTree = do
files <- toList <$> filesIO
sequence_ $ success <$> files
testSuite
时生成的输出is run 不是很具有描述性。
Files that should successfully be parsed
Valid files
Unexpected parse errors: OK (6.54s)
Files that should successfully be parsed
Valid files
Unexpected parse errors: FAIL (3.40s)
path/to/files/fileB
Files that should successfully be parsed
Valid files
"path/to/files/fileA": OK (2.34s)
"path/to/files/fileB": OK (3.45s)
"path/to/files/fileC": OK (4.56s)
Files that should successfully be parsed
Valid files
"path/to/files/fileA": OK (2.34s)
"path/to/files/fileB": FAIL (3.45s)
"path/to/files/fileC": FAIL (4.56s)
TestTree
从文件系统动态:
-- | How I would like the code to work, except for the `unsafePerformIO` call
testSuite' :: TestTree
testSuite' = testGroup "Files that should successfully be parsed" [withResource validContents release validateFiles]
where
validContents = getFileContentsInDirectory "path/to/files"
release = const $ pure ()
parse' :: (FilePath,String) -> Either ParseError a
parse' (path,content) = parse myFileParser path content
success :: (FilePath,String) -> TestTree
success (path,content) = testCase (show path) . assert . isRight $ parse' (path,content)
validateFiles :: IO (Map FilePath String) -> TestTree
validateFiles !filesIO = testGroup "Valid files" $ unsafePerformIO fileTree
where
fileTree :: IO [TestTree]
fileTree = fmap success . toList <$> filesIO
unsafePerformIO
调用此代码以提取
TestTree
通过
unsafePerformIO :: IO [TestTree] -> [TestTree]
.我觉得不得不使用这个不安全的函数调用,因为我不知道如何使用从
testCase
中的文件系统(文件名)派生的信息。建筑。结果
[TestTree]
was trapped在
IO
单子(monad)。
IO
行动实际上是不安全的。测试套件永远不会运行,因为引发了以下异常:
*** Exception: Unhandled resource. Probably a bug in the runner you're using.
withResource
的类型签名:
withResource :: IO a -- initialize the resource
-> (a -> IO ()) -- free the resource
-> (IO a -> TestTree) -- IO a is an action which returns the acquired resource. Despite it being an IO action, the resource it returns will be acquired only once and shared across all the tests in the tree.
-> TestTree
IO a -> TestTree
类型的函数对于
withResource
的最后一个参数不使用
IO a
输入
TestName
testCase
的参数或
testGroup
来电。尽管审查了
Tasty
框架作者
verbose explanation ,也许我想念如何
withResources
应该是使用的。或许 Tasty 框架内有更好的功能来实现想要的
TestTree
?
TestTree
来自具有所需描述性输出的文件系统?
最佳答案
您不能通过资源动态构造 TestTree 的事实是非常有意的。当我写 here ,
One of the major problems with tests receiving the resource value directly, as in
withResource
:: IO a
-> (a -> IO ())
-> (a -> TestTree)
-> TestTree... was that the resource could be used not only in the tests themselves, but to construct the tests, which is bad/wrong for a number of reasons. For instance, we don't want to create the resources when we're not running tests, but we still want to know which tests we have.
main
可以不仅仅是
defaultMain
.确实,它可以利用IO的全部威力来构造一个测试树,然后调用
defaultMain
使用动态构建的测试树。
main = do
testTree <- constructTestTree
defaultMain testTree
关于unit-testing - 从文件系统动态生成 Tasty `TestTree`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33040722/
我有以下功能: fun process(t: T, call: (U) -> Unit, map: (T) -> U) = call(map(t)) fun processEmpty(t: T,
关闭。这个问题需要更多focused .它目前不接受答案。 想改善这个问题吗?更新问题,使其仅关注一个问题 editing this post . 4年前关闭。 Improve this questi
我正在实现 SVG Tiny 1.1,但我无法理解“用户单元”的概念。 SVG 1.1 规范将每个没有指定单位(例如“mm”、“cm”、“pt”等)的 定义为“用户单位”。 在实现接口(interfa
我正在学习本教程 - http://blog.dasberg.nl/getting-your-frontend-code-quality-in-order/ - 将前端质量指标推送到 SonarQub
我用了 rails new app --skip-test-unit 因为最初,我认为我可以稍后添加测试。 我开发了我的应用程序的很大一部分。 现在,我想添加 Test::Unit 但我找不到任何有关
您如何对由某些报表引擎(例如Crystal Reports或SQL Server Reporting Services)创建的报表进行“单元测试”? 最佳答案 报告的问题类似于GUI的问题。 如果报表
今天在 Proggit 上,我正在阅读题为“Why Unit Testing Is A Waste of Time”的提交的评论线程。 我并不真正关心文章的前提,而是关心 comment对此作出: T
“单元测试”属于白盒测试还是黑盒测试?还是与其他两种测试完全不同? 最佳答案 我觉得这个article by Kent Beck更多地引用 TDD 和单元测试很好地总结了这一点。基本上,这取决于您实际
这是代码: def filterAcc(p: Tweet => Boolean, acc: TweetSet): TweetSet = { foreach(tweet => if(p(el
我打算编写一个抽象类来测试我所有的 DTO 和 DOMAIN 对象。此类将采用可模板对象(通用类型)并使用反射来获取其中的属性类型,并将一些默认值分配给标识的原始类型,稍后将通过访问它们来断言这些类型
我有一个像这样的简单容器特征: trait Handler { def apply[In, Out](in: In): Out } 当我尝试实现它时: new Handler { def ap
为什么这样编译 scala> import scala.concurrent.Future import scala.concurrent.Future scala> val f: Unit = Fu
您使用什么样的实践来使您的代码对单元测试更加友好? 最佳答案 TDD——首先编写测试,强制你要考虑可测试性和帮助编写实际的代码需要的,而不是你认为可能的需要 接口(interface)重构——使得 m
我在elasticsearch中有文本字段,我想在kibana上可视化词云... 第一步,我们需要标记它们,我使用了“标准标记器” ... 使用这种形式的词云可视化结果如下图所示: 但是我需要的是专有
我有以下方法: override def insertAll(notifications: Seq[PushNotificationEncoded]) (i
我的应用程序服务层中有很多方法正在做这样的事情: public void Execute(PlaceOrderOnHoldCommand command) { var order = _rep
一直在使用 Sails.js,但在为 Controller 设计 Jasmine 单元测试时遇到了麻烦。如果这很明显,请原谅我的无知,因为在过去的 3-4 个月里我才深入研究 JavaScript 开
Closed. This question does not meet Stack Overflow guidelines。它当前不接受答案。 想改善这个问题吗?更新问题,以便将其作为on-topic
在ReKotlin repo README中,有如下代码: data class CounterActionIncrease(val unit: Unit = Unit): Action 代码Unit
我想对一个业务类进行测试,但我遇到了这个问题:其中一个模拟对象与其他类(例如 Sites、URL 和 ComplexObject)有许多依赖关系。 我的问题是:如果我必须在需要测试的方法中使用我的模拟
我是一名优秀的程序员,十分优秀!