资讯专栏INFORMATION COLUMN

PHPUnit实践三(构建模块化的测试单元)

goji / 2701人阅读

摘要:本系列教程所有的测试基于版本,框架目录结构模块下的目录是符合的模块结构的如等是模块目录下的结构目录如果有自己的目录同级分配即可,如我这里的整体结构重写过基类的测试基类,用于我们用这个基类做测试基类,后续会说明自动加载文件测试用例目录某测试模

本系列教程所有的PHPUnit测试基于PHPUnit6.5.9版本,Lumen 5.5框架

目录结构

模块下的目录是符合Lumen的模块结构的
如:Controllers、Models、Logics等是Lumen模块目录下的结构目录
如果有自己的目录同级分配即可,如我这里的Requests

整体结构
├── BaseCase.php 重写过Lumen基类的测试基类,用于我们用这个基类做测试基类,后续会说明
├── bootstrap.php tests自动加载文件
├── Cases 测试用例目录
│   └── Headline 某测试模块
│       ├── logs 日志输出目录
│       ├── PipeTest.php PHPUnit流程测试用例
│       ├── phpunit.xml phpunit配置文件xml
│       └── README.md 本模块测试用例说明
├── ExampleTest.php 最原始测试demo
└── TestCase.php Lumen自带的测试基类
某模块的目录结构
Headline  //某测试模块测试用例目录
├── Cache
├── Controllers
│   ├── ArticleTest.php
│   ├── ...
├── Listeners
│   └── MyListener.php
├── Logics
├── Models
│   ├── ArticleTest.php
│   ├── ...
├── README.md
├── Requests
│   ├── ArticleTest.php
│   ├── ...
├── logs //日志和覆盖率目录
│   ├── html
│   │   ├── ...
│   │   └── index.html
│   ├── logfile.xml
│   ├── testdox.html
│   └── testdox.txt
├── phpunit-debug-demo.xml   //phpunit.xml案例
├── phpunit-debug.xml        //改名后测试用的
└── phpunit.xml              //正式用的xml配置
BaseCase.php
 "token*",
        "dev" => "token*",
        "prod" => "" //如果测试真实请填写授权token
    ];

    /**
     * 重写setUp
     */
    public function setUp()
    {
        parent::setUp();

        $this->seeder = false;
        if (method_exists($this, "factory")) {
            $this->app->make("db");
            $this->factory($this->app->make(Factory::class));

            if (method_exists($this, "seeder")) {
                if (!method_exists($this, "seederRollback")) {
                    dd("请先创建seederRollback回滚方法");
                }
                $this->seeder = true;
                $this->seeder();
            }
        }
    }

    /**
     * 重写tearDown
     */
    public function tearDown()
    {
        if ($this->seeder && method_exists($this, "seederRollback")) {
            $this->seederRollback();
        }

        parent::tearDown();
    }

    /**
     * 获取地址
     * @param string $apiKey
     * @param string $token
     * @return string
     */
    protected function getRequestUri($apiKey = "list", $token = "dev", $ddinfoQuery = true)
    {
        $query = "?token=" . static::TOKEN[strtolower($token)];
        if ($ddinfoQuery) {
            $query = $query . "&" . http_build_query(static::DDINFO);
        }

        return $apiUri = static::DOMAIN . static::API_URI[$apiKey] . $query;
    }
}
phpunit-debug-demo.xml

本文件是我们多带带为某些正在测试的测试用例,直接编写的xml,可以不用来回测试,已经测试成功的测试用例了,最后全部编写完测试用例,再用正式phpunit.xml即可,具体在运行测试阶段看如何指定配置




    
        
            ../../../app/Http/Controllers/Headline
            ../../../app/Http/Requests/Headline
            ../../../app/Models/Headline
            ../../../app/Models/Headline/ArticleKeywordsRelationModel.php
            
        
    

    
        
            ./
        
    

    
        
        
    

    
        
        
        
        
        
        
    

    
        
            
                
                    
                        
                    
                
                
                
                
                
                
            
        
        
            
                
                    
                        
                    
                
                
            
        
    
测试用例案例
define(ArticlesModel::class, function (Generator $faker) use (&$id, $words) {
            $id++;
            return [
                "id" => $id,
                "uri" => $faker->lexify("T???????????????????"),
                "title" => $id == 263 ? "搜索" : $words[rand(0, sizeof($words) - 1)],
                "authorId" => 1,
                "state" => 1,
                "isUpdated" => 0,
            ];
        });
    }

    /**
     * 生成模拟的数据,需seederRollback 成对出现
     */
    public function seeder()
    {
        $articles = factory(ArticlesModel::class, 10)->make();
        foreach ($articles as $article) { // 注意: article为引用对象,不是copy
            if ($article->isRecommend) {
                $article->recommendTime = time();
            }
            $article->save();
        }
    }

    /**
     * getArticleList 测试数据
     * @return array
     */
    public function getArticleListDataProvider()
    {
        return [
            [1, "搜索", 1, 10, 1],
            [2, "搜索", 1, 10, 0],
            [2, null, 1, 10, 0],
            [3, "搜索", 1, 10, 0],
            [1, null, 1, 10, 1],
            [2, null, 1, 10, 0],
            [3, null, 1, 10, 0],
        ];
    }

    /**
     * @dataProvider getArticleListDataProvider
     */
    public function testGetArticleList($type, $searchText, $page, $pageSize, $expceted)
    {
        $rst = self::$model->getArticleList($type, $searchText, $page, $pageSize);

        $this->assertGreaterThanOrEqual($expceted, sizeof($rst));

        $rst = self::$model->getArticleCount($type, $searchText);

        $this->assertGreaterThanOrEqual($expceted, $rst);
    }

    /**
     * addArticle 测试数据
     * @return array
     */
    public function addArticleDataProvider()
    {
        return [
            [
                [
                    "id" => 273,
                    "uri" => "ffffdffffdffffdd0123"
                ],
                "save",
                0
            ],
            [
                [
                    "id" => 274,
                    "uri" => "ffffdffffdffffdd123"
                ],
                "publish",
                0
            ],
            [
                [
                    "id" => 275,
                    "uri" => "ffffdffffdffffdd456"
                ],
                "preview",
                0
            ],
        ];
    }

    /**
     * @dataProvider addArticleDataProvider
     */
    public function testAdd($data, $action, $expected)
    {
        $rst = self::$model->addArticle($data, $action);

        if ($rst) {
            self::$model::where("id", $rst)->delete();
        }

        $this->assertGreaterThanOrEqual($expected, $rst);
    }

    public function testGetArticleInfo()
    {
        $rst = self::$model->getArticleInfo(263, 0);

        $this->assertGreaterThanOrEqual(1, sizeof($rst));

        $rst = self::$model->getArticleInfo(2000, 1);

        $this->assertEquals(0, sizeof($rst));
    }


    /**
     * 回滚模拟的数据到初始状态
     */
    public function seederRollback()
    {
        self::$model::where("id", ">=", 263)->where("id", "<=", 272)->delete();
    }
}
运行测试
cd {APPROOT}/tests/Cases/Headline
# mv phpunit-debug-custom.xml -> phpunit-debug.xml
../../../vendor/bin/phpunit --verbose -c phpunit-debug.xml
参考

PHPUnit 5.0 官方中文手册

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/30105.html

相关文章

  • Travis CI 持续集成服务构建 Composer 类库简明教程

    摘要:创建帐号提供的是持续集成服务,简称。在这里引入的原因是我们的项目需要使用服务进行持续集成和测试,当然你也可以替换成别的单元测试工具。创建单元测试用例是单元测试类库家族中的一员,使用的一个主要目的是为我们的模块创建单元测试用例。 本文首发于 Travis CI 持续集成服务构建 Composer 类库简明教程,转载请注明出处! 在项目开发过程中,编码工作只是软件开发整个过程中的一小部分环...

    DoINsiSt 评论0 收藏0
  • PHPUnit实践一(初识)

    摘要:另外一些单元测试可能会测试负向路径的场景,保证代码不仅会产生错误,而且是预期的错误。是一个面向程序员的测试框架,这是一个的体系结构的单元测试框架。 本系列教程所有的PHPUnit测试基于PHPUnit6.5.9版本,Lumen 5.5框架 前置 日常我们的普通用到的测试: 代码直接echo,debug等方法测试 -> 跟踪细节断点型测试 log日志辅助测试 -> 跟踪细节断点型测试 ...

    weapon 评论0 收藏0
  • PHPUnit实践一(初识)

    摘要:另外一些单元测试可能会测试负向路径的场景,保证代码不仅会产生错误,而且是预期的错误。是一个面向程序员的测试框架,这是一个的体系结构的单元测试框架。 本系列教程所有的PHPUnit测试基于PHPUnit6.5.9版本,Lumen 5.5框架 前置 日常我们的普通用到的测试: 代码直接echo,debug等方法测试 -> 跟踪细节断点型测试 log日志辅助测试 -> 跟踪细节断点型测试 ...

    hss01248 评论0 收藏0
  • 使用桩件 (Stub) 解决 Laravel 单元测试依赖

    摘要:可是我们在做单元测试的时候,希望尽可能少的产生依赖。后记任何一个可靠的系统,单元测试都是必不可少的。庆幸的是,帮我们提供了好用的单元测试。 本文是我在实践后的一点总结,难免有不妥之处。如有幸得大神路过,还望不吝赐教,小弟在此谢过了! 很早就知道有单元测试的概念,也曾尝试过,但是一直对单元测试的概念和方法,比较模糊。在听了 @vimac 大神的讲堂 PHP单元测试与测试驱动开发 后,慢慢...

    Miyang 评论0 收藏0
  • phpunit PHP单元测试利器

    摘要:是的单元测试框架。单元测试在软件开发中越来越受到重视,测试先行编程极限编程和测试驱动开发在实践中被广泛。利用单元测试,也可以实现契约式设计。现在第二个测试也能通过啦你也可以使用契约式设计的风格,只需使用类提供的静态断言方法编写契约条件。 PHPUnit是PHP的单元测试框架。单元测试在软件开发中越来越受到重视,测试先行编程、极限编程和测试驱动开发在实践中被广泛。利用单元测试,也可以实现...

    wyk1184 评论0 收藏0

发表评论

0条评论

goji

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<