随笔 - 230  文章 - 0 评论 - 0 阅读 - 88424
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

Apisix单元测试

可参考官网的教程:
https://apisix.apache.org/blog/2022/06/27/getting-start-with-apisix-test-cases/

准备条件:

测试
在apisix中有个 t 文件夹,内部都是放的测试文件,借助于test::Apisix.使用perl语言进行测试,还是比较麻烦。
但是apisix又需要nginx,因此,需要安装test::nginx

cpan Test::Nginx

APISIX.pm

apisix的测试和apisix的加载过程本身不是一条路线。APISIX.pm 内部定义了自己用的etcd的地址,而非我们config.yaml中定义的地址。

etcd

测试时,确认当前local环境下存在etcd地址,不然路由无法启动。
image

lua_shared

lua_shared也没有使用config-default.yml中配置内容。而是使用apisix.pm中写的,因此,共享变量要在此处提前定义好。

配置

config:
apisix在执行测试时,会将当前文件夹/config/config-default.yaml文件copy到/t/servroot/下。因此,插件及其插件配置信息要执行测试,需要配置到config-default.yaml中。
日志:
日志会输出到/t/servroot/log 下,每次执行都会销毁重建。

执行:

PATH=/usr/local/openresty/nginx/sbin:/usr/bin PERL5LIB=.:$PERL5LIB FLUSH_ETCD=1 prove -Itest-nginx/lib t/plugin/my-test.t

测试编写:

文件头统一

use t::APISIX 'no_plan';

repeat_each(1);
no_long_string();
no_root_location();
no_shuffle();

# 定义log配置
add_block_preprocessor(sub {
    my ($block) = @_;

    if ((!defined $block->error_log) && (!defined $block->no_error_log)) {
        $block->set_value("no_error_log", "[error]");
    }

    if (!defined $block->request) {
        $block->set_value("request", "GET /t");
    }
});


run_tests;

__DATA__

测试示例:helloworld

=== TEST 1: helloworld
--- config
    location /t {
        content_by_lua_block {
            ngx.say("hello, world")
        }
    }
--- request
GET /t
--- response_body
hello, world
--- error_code: 200
--- no_error_log
[error]

校验Schema

执行check时,会自动触发模块的init()方法。
Schema的写法参照:
https://json-schema.apifox.cn/

=== TEST 2: configtest1
--- config
    location /t {
        content_by_lua_block {
            local my_schemas = {
			 {},
			 {my_list={}},
            }
            local plugin = require("apisix.plugins.my_test")
            for _, case in ipairs(my_schemas) do
                local ok, err =  plugin.check_conf(case)
                ngx.say(ok and "done" or err)
            end
        }
    }
--- response_body
property "my_list" is required
property "my_list" validation failed: expect array to have at least 1 items
done
--- no_error_log
[error]

路由添加插件

=== TEST 4: write my-test plugin
--- config
    location /t {
        content_by_lua_block {
            local t = require("lib.test_admin").test
            local code, body = t('/apisix/admin/routes/123',
                 ngx.HTTP_PUT,
                 [[{
                        "plugins": {
                            "my-test": {
                              "my_list":           ["172.20.55.55:8000"]
                        },
                        "upstream": {
                            "nodes": {
                                "127.0.0.1:5000": 1
                            },
                            "type": "roundrobin"
                        },
                        "uri": "/*"
                }]]
                )
            if code >= 300 then
                ngx.status = code
            end
            ngx.say(body)
        }
    }
--- request
GET /t
--- response_body
passed
--- error_log
[error]

路由请求访问

Test3中的配置可以直接在Test4中使用,无需重新建立测试路由

=== TEST 5: hit route (with correct request)
--- request
GET /hello?test=AAAA&user=none
--- more_headers
test-header: only-for-test
--- response_body
hello world AAAA!

=== TEST 6: hit route2 (with correct request)
--- request
GET /hello?test=BBB
--- more_headers
test-header: only-for-test
--- response_body
hello world BBB!
posted on   zhaoqiang1980  阅读(50)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示