ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Regal 规则详解:test-outside-test-package —— 用 `_test` 后缀包将 Rego 测试与生产策略分离

Regal 规则详解:test-outside-test-package —— 用 `_test` 后缀包将 Rego 测试与生产策略分离 后端认证鉴权云原生【免费下载链接】opaOpen Policy Agent (OPA) is an open source, general-purpose policy engine.项目地址https://gitcode.com/gh_mirrors/op/opa点击查看免费下载本文聚焦 Open Policy AgentOPA配套的 Rego 静态检查工具 Regal 中的test-outside-test-package规则。该规则属于 Regal 的 Testing 规则类别核心要求是测试代码应放在带_test后缀的独立包package中而不是与生产策略混在同一个包里。读完本文你将理解 OPA 测试运行器的发现机制、_test包约定的来龙去脉掌握可复制运行的合规/违规示例并能通过 Regal 配置文件把该规则调整到适合自己团队的严重级别。一、规则速览项目内容规则名称test-outside-test-package摘要Summary测试应写在测试包之外Test outside of test package所属类别CategoryTesting测试默认严重级别error核心诉求测试规则不得与生产策略处于同一个 package该规则完整定义见仓库文档 test-outside-test-package.mdRegal 全部 Testing 类规则入口见 rules/testing/index.md。二、背景先理解opa test的测试发现机制要理解这条规则为什么成立需要先明白 OPA 测试运行器如何找到测试。OPA 官方文档 policy-testing.md 明确指出测试以普通 Rego 规则形式编写约定规则名以test_前缀开头opa test子命令会运行命令行传入的 Rego 文件中所有以test_前缀开头的规则如果传入的是目录会递归加载目录内容测试规则若未定义或求值结果不为true报告为FAIL遇到运行时错误如除零标记为ERROR以todo_前缀开头的测试报告为SKIPPED其余为PASS。这一机制在 OPA 源码中也有明确实现。在 tester/tester.go 中// TestPrefix declares the prefix for all test rules. const TestPrefix v1.TestPrefix // SkipTestPrefix declares the prefix for tests that should be skipped. const SkipTestPrefix v1.SkipTestPrefix其具体取值定义在 v1/tester/runner.go// TestPrefix declares the prefix for all test rules. const TestPrefix test_ // SkipTestPrefix declares the prefix for tests that should be skipped. const SkipTestPrefix todo_test_而在 v1/tester/runner.go 的规则筛选逻辑中运行器正是通过strings.HasPrefix(n, TestPrefix) || strings.HasPrefix(n, SkipTestPrefix)来判定一条规则是否为测试并据此决定是否纳入本次opa test执行。关键结论OPA 的测试发现只认规则名的前缀与规则所在包名毫无关系。也就是说把test_规则写在package policy里OPA 同样会执行它——这正是test-outside-test-package规则要纠正的写法。三、违规写法Avoid测试与策略同包当测试直接写在生产策略所在的包里时Regal 会触发test-outside-test-package违规。原文档给出的违规示例package policy allow if { admin in input.user.roles } # Tests in same package as policy test_allow_if_admin { allow with input as {user: {roles: [admin]}} }这段代码的问题不在于不能运行——opa test依然会执行test_allow_if_admin并成功通过断言。问题在于代码组织测试与生产规则共享同一个命名空间data.policy测试规则会被当作data.policy.test_allow_if_admin暴露在数据文档中与allow这样的业务规则混在一起。四、推荐写法Prefer独立的_test后缀包原文档给出的合规写法是把测试放进带_test后缀的独立包并通过import data.policy引入被测策略# Tests in separate package with _test suffix package policy_test import data.policy test_allow_if_admin { policy.allow with input as {user: {roles: [admin]}} }两种写法的差异对比维度Avoid同包Prefer_test包测试包名policypolicy_test测试在数据文档中的路径data.policy.test_allow_if_admindata.policy_test.test_allow_if_admin访问被测规则直接引用allowimport data.policy后引用policy.allow测试与生产规则的耦合混在一起完全隔离能否单独构建/打包生产策略测试规则会混入可以干净地排除这里用到的with input as {...}是 OPA 测试的核心语法在求值测试规则时用给定的对象临时替换input文档。除了替换input还可以用with data.x as y替换任意数据文档例如test_allow_with_data if { policy.allow with input as {user: alice, role: admin} with data.policies as policies with data.roles as roles }更完整的with用法示例可以参考 policy-testing.md 中的 Test Data 章节。五、设计动机Rationale为什么要把测试请出生产包原文档对规则动机的说明是虽然 OPA 的测试运行器会执行任何带test_前缀的规则但将测试与生产策略清晰分离是良好实践。具体来说这种分离带来几方面收益意图清晰看包名就知道policy_test里只有测试policy里只有逻辑代码审查、维护和检索成本都更低。避免生产 bundle 混入测试代码OPA 在构建 bundle 时测试文件需要被排除例如很多构建流水线会排除*_test.rego这类文件。测试与策略处于同一包时排除粒度只能到文件容易误伤或遗漏而_test包 _test.rego文件名让排除规则可以精确、可靠。与文件名约定相辅相成该规则要求包名带_test后缀而配套规则 file-missing-test-suffix 要求存放测试的文件以_test.rego结尾理想情况为policy.rego对应policy_test.rego。两者共同构成一套完整的测试组织规范_test后缀的包名 _test.rego后缀的文件名。值得一提的是该规则与另一条 Idiomatic 类规则 directory-package-mismatch 有明确的协作关系后者默认设置exclude-test-suffix: true即在比对目录结构是否镜像包路径时忽略_test后缀——也就是说package policy_test中的测试文件可以安心放在policy/目录下紧挨着被测文件这不会与test-outside-test-package的_test包要求冲突。Regal 社区普遍采用测试文件与被测文件同目录、测试包名加_test后缀的组织方式。六、配套实操搭建一个完全合规的测试项目把前面几节的内容串起来一个完全符合test-outside-test-package以及file-missing-test-suffix、directory-package-mismatch规则的完整项目结构如下$ ls policy.rego policy_test.rego被测策略policy.regopackage policy allow if { admin in input.user.roles }测试文件policy_test.rego与策略同目录包名加_test后缀package policy_test import data.policy test_allow_if_admin { policy.allow with input as {user: {roles: [admin]}} } test_deny_if_not_admin { not policy.allow with input as {user: {roles: [user]}} }运行测试$ opa test . -v data.policy_test.test_allow_if_admin: PASS (1.417µs) data.policy_test.test_deny_if_not_admin: PASS (426ns) -------------------------------------------------------------------------------- PASS: 2/2运行 Regal 静态检查$ regal lint .如果一切合规regal lint不会报告任何问题一旦你把测试规则移回package policyRegal 就会按test-outside-test-package的默认error级别报告违规并使命令以非零退出码结束。其他对测试实践有帮助的opa test能力还包括用--run/-r正则精确指定要运行的测试、用--fail-on-empty在没有测试运行时让命令失败对 CI 很有用、用--formatjson输出结构化测试结果、用--var-values在失败报告中展示表达式中各变量的取值详细说明同样见 policy-testing.md。七、配置选项把规则强度交给团队决定test-outside-test-package提供以下配置选项rules: testing: test-outside-test-package: # one of error, warning, ignore level: error配置文件中level有三个可选值含义依据 Regal 的 configuration/index.mdignore—— 完全禁用该规则warning—— 报告违规但不改变regal lint的退出码error—— 报告违规且regal lint以非零退出码结束默认值。Regal 会按以下优先级定位配置文件详见 configuration/index.md当前目录下的.regal/config.yaml或.regal.yaml若当前目录未找到则逐级向父目录遍历查找用户级配置文件如~/.config/regal/config.yaml以上都没有时使用 Regal 内置的默认配置。也可以通过regal lint --config-file/-c path显式指定配置文件覆盖默认配置见 cli.md。实际项目中通常建议把配置文件提交到仓库让团队共享同一套规则强度也使 Regal 作为 CI linter 运行时行为一致。八、Testing 规则族与test-outside-test-package配套的其他检查test-outside-test-package是 Regal Testing 类别rules/testing/index.md中的一员。同一个类别下还有多条定位互补的规则共同覆盖 Rego 测试的各个维度规则解决的问题文档file-missing-test-suffix包含测试的文件应以_test.rego结尾且建议与被测文件同名前缀file-missing-test-suffix.mdidentically-named-tests同一测试包内禁止出现重名的测试规则identically-named-tests.mdtodo-test禁止提交以todo_开头的未完成测试todo-test.mdprint-or-trace-call测试中不应残留print/trace调试调用print-or-trace-call.mddubious-print-sprintf捕捉测试中可疑的print/sprintf用法dubious-print-sprintf.mdmetasyntactic-variable捕捉foo、bar之类的占位变量名metasyntactic-variable.md这些规则与test-outside-test-package一起构成了一套测试该怎么放、怎么命名、怎么写的完整规范。关于 Regal 本身的定位、安装与使用方式可参考 Regal 介绍文档。九、常见疑问与边界Q1OPA 是否强制要求测试放在_test包里不强制。如 policy-testing.md 原文所述Its a good practice for tests to be placed in a package suffixed with_test, but not a requirement.建议但不是必须。test-outside-test-package是 Regal 这一静态检查工具提出的规范而非 OPA 运行时的硬性约束——这正是它需要通过配置level交由团队决策的原因。Q2这条规则是否影响参数化测试data-driven tests不影响。opa test支持在规则头中声明测试用例名如test_concat[note] if {...}其以test_前缀识别测试的机制对参数化测试同样适用。分离到_test包后参数化测试写法不变只需通过import data.policy引用被测规则。Q3测试文件到底该放在哪个目录test-outside-test-package只约束包名必须带_test后缀不强制测试文件必须放在_test目录。与 directory-package-mismatch 配合时默认行为exclude-test-suffix: true允许policy_test包的文件与policy包的文件同处policy/目录只有当团队把exclude-test-suffix设为false时才要求_test包必须位于_test目录。两种组织方式皆可关键是团队内保持一致。十、小结test-outside-test-package虽然只是一条看似简单的命名约定但它与 OPA 测试运行器的前缀发现机制v1/tester/runner.go 中的TestPrefix判定形成鲜明对照OPA 只关心规则名Regal 则替你关心代码组织。将测试放入_test后缀的独立包配合_test.rego文件命名file-missing-test-suffix和目录-包镜像约定directory-package-mismatch就能让策略仓库在生产逻辑与测试之间保持清晰的边界既便于维护也便于构建干净的 bundle。通过 Regal 配置文件你可以按团队规范将该规则设为error、warning或ignore让静态检查的强度始终与团队的实际工作流对齐。赞分享后端认证鉴权云原生【免费下载链接】opaOpen Policy Agent (OPA) is an open source, general-purpose policy engine.项目地址https://gitcode.com/gh_mirrors/op/opa点击查看免费下载相关推荐使用 Tushare hk_basic 构建港股证券池Vibe-Trading 港股基础信息接入实战使用 Tushare hk_basic 构建港股证券池Vibe Trading 港股基础信息接入实战 本文以 Tushare 数据接口 hk_basic 为核后端认证鉴权云原生Regal trailing-default-rule 规则详解让 default 规则声明先行提升 Rego 策略可读性Regal trailing default rule 规则详解让 default 规则声明先行提升 Rego 策略可读性 导读 本文聚焦 Open Pol后端认证鉴权云原生PHP-CS-Fixer 的 php_unit_test_annotation 规则统一 PHPUnit 测试命名风格test 注解 vs test 前缀PHP CS Fixer 的 php_unit_test_annotation 规则统一 PHPUnit 测试命名风格test 注解 vs test 前缀开发工具代码质量静态分析Lint格式化上一篇猫抓插件浏览器资源嗅探的终极解决方案下一篇猫抓插件你的浏览器资源嗅探专家创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表