测试模式和排除模式是可选的,但却是配置文件的重要部分。 .deepsource.toml配置文件的重要部分。它们被写成glob模式。这些模式在减少DeepSource为项目提出的问题中的噪音和假阳性方面发挥着重要作用。
什么是Glob?
Glob或 "Shell Globing "是指编写glob模式来匹配文件系统中的文件的过程。Glob模式指定带有通配符的文件名集合。例如,Unix Bash shell命令rm -rftextfiles/*.txt 从textfiles文件夹中删除(rm)所有名称以.txt结尾的文件。在这里,* 是一个通配符,当与.txt 结合时,会产生*.txt ,这是一个glob模式。
除了匹配文件名之外,glob还可以用来匹配任意字符串(通配符匹配),比如? ,它可以匹配单个字符。
但是,由于我们的重点是编写测试文件和排除文件模式,所以我们将重点讨论通配符,例如*,** 和/ ,这些通配符广泛用于编写项目中匹配文件的 glob 模式。
*匹配任何字符串,包括空字符串。就像上面的例子textfiles/*.txt,其中'*'匹配所有名字以 "*"结尾的文件。/是一个常见的字符,被广泛用作路径分隔符。**是被称为globstar的特征,它匹配所有的文件和零个或更多的目录和子目录。如果后面有一个 ,它只匹配目录和子目录。要以这种方式工作,它必须是路径部分中唯一的东西,例如,/Demo/**.py就不能以这种方式工作。
DeepSource配置中的Globs
DeepSource配置中有两个部分可以使用glob模式:exclude_patterns 和test_patterns 。
exclude_patterns这是一个glob模式的列表,在运行分析的时候应该被排除。这些模式应该是相对于版本库的根的。test_patterns是一个应该被标记为测试或包含测试文件的glob模式的列表。这些模式也应该是相对于版本库的根的。
默认情况下,DeepSource 会检查每个文件并对所有文件进行分析。在.deepsource.toml 中设置exclude_patterns 和test_patterns 配置,使 DeepSource 对你的代码有更多的了解。然后,DeepSource可以有选择地分析那些重要的文件。
一个快速的例子以及为什么你需要globs
在编写Python代码时,如果你不在test-patterns 中标记你的测试文件,DeepSource就会检测到assert语句的用法。assert 提供了一种简单的方法来检查一些条件并失败执行,对于开发人员来说,使用它来检查有效性是非常普遍的。但是,当Python解释器用-O (优化)标志调用时,断言语句会从字节码中删除。
因此,如果在生产代码中使用 assert 语句进行面向用户的验证,那么这个块根本就不会被执行 - 可能会打开一个安全漏洞。我们建议只在测试中使用断言语句。因此,为了避免DeepSource提出这样的问题,必须在test_patterns 中添加测试文件。
这里是一个配置样本,有一些测试和排除模式的例子。
version = 1
test_patterns = [
"tests/**",
"test_*.py",
"*_test.rb\""
]
exclude_patterns = [
"migrations/**",
"*/examples/**"
]
[[analyzers]]
name = "python"
enabled = true
[analyzers.meta]
runtime_version = "3.x.x"
[[analyzers]]
name = "ruby"
enabled = true
缺少或错误的模式会增加噪音
让我们看看当我们错误地编写test_patterns时会发生什么。FOSSASIA在他们的一个名为open-event-server的项目中把测试文件模式写成了*/tests/** ,这导致了问题的总数达到了1700+左右。

但通过一个PR的简单修复,将测试文件模式更新为tests/** ,使得DeepSource提出的问题减少到1500个左右。

正确编写glob模式
现在让我们为测试和排除模式编写自己的glob模式。我们将使用Glob Tester工具来测试我们的模式,然后在配置中使用它们。
假设,我们有一个这样的项目结构。
src/
|---app.py
|---api/
| |--- __init__.py
| |--- middleware.py
| |--- routes/
| |--- auth/
| | |--- register.py
| | |--- login.py
| |--- posts/
| | |--- get.py
| | |--- create.py
| |--- comments/
| | |--- get.py
| | |--- create.py
| |--- utils/
| | |--- security.py
| | |--- error.py
|--- models/
| |--- comments.py
| |--- posts.py
| |--- users.py
|--- tests/
| |--- __init__.py
| |--- router/
| |--- test_auth.py
| |--- test_posts.py
| |--- test_comments.py
|--- migrations/
| |--- env.py
| |--- scripts.py
|--- examples/
| |--- example.py
|--- .gitignore
|--- Procfile
|--- README.md
去看这个Glob Tester Tool的例子,玩玩这个文件结构。
测试文件模式
这里所有重要的目录都是/src/ 的子目录。 匹配/src/tests/ 目录下所有文件的glob模式应该写成*/tests** - 其中*/ 表示匹配一个字符串,后面有一个路径分隔符。
因此,如果我们在DeepSource配置中使用*/tests/** 作为测试文件模式之一,DeepSource将在根目录下寻找一个名为tests 的目录,然后递归地寻找其中的所有文件。

使用Glob Tester工具根据glob模式寻找匹配的文件路径
带有这个值的配置将看起来像。
test_patterns = ["*/tests/**"]
提示:如果一个项目中有多个tests 子目录,同样的glob模式将不起作用。你的模式将变为**/tests/** -**/ ,在开始的时候,会递归地匹配所有子目录中出现的tests 目录。
排除文件模式
我们可以编写exclude_patterns 来忽略像examples 和migrations 这样的目录。你的glob模式将看起来像。
exclude_patterns = [
"*/examples/**",
"*/migrations/**"
]
完整的配置
将它们结合在一起,这就是.deepsource.toml 中的完整配置的样子。
version = 1
test_patterns = ["*/tests/**"]
exclude_patterns = [
"*/migrations/**",
"*/examples/**"
]
[[analyzers]]
name = "python"
enabled = true
[analyzers.meta]
runtime_version = "3.x.x"