Vapor 3 test tools

Slack Jenkins Platforms Swift Package Manager License Platform

Vaper 测试工具(基本上正如其名)是一组旨在使在 Vapor 3 中测试端点更加轻松的方法...

Slack

在 Vapor Slack 上获取有关使用和/或安装此库的帮助,并查找 @rafiki270

示例

要在 Mac 上运行示例项目,请克隆 repo,并运行 vapor xcode 以生成 xcode 项目并运行 Run 目标。

安装

SPM - Swift 包管理器

导入

.package(url: "https://github.com/LiveUI/VaporTestTools.git", from: "0.1.1")

// or to always get the latest changes

.package(url: "https://github.com/LiveUI/VaporTestTools.git", .branch("master"))

用法

要编写像这样的测试...

func testHello() {
    let req = HTTPRequest.testable.get(uri: "/hello")
    let res = app.testable.response(to: req).response

    res.testable.debug() // Debug response into the console
    
    let hello = res.testable.content(as: Hello.self)!
    XCTAssertEqual(hello.message, "hello world", "Message is incorrect")

    XCTAssertTrue(res.testable.has(statusCode: .ok), "Wrong status code")
    XCTAssertTrue(res.testable.has(contentType: "text/plain; charset=utf-8"), "Missing content type")
    XCTAssertTrue(res.testable.has(contentLength: 13), "Wrong content length")
    XCTAssertTrue(res.testable.has(content: "Hello, world!"), "Incorrect content")
}

... 你首先需要在测试环境中配置你的 Application 对象。为此,我建议创建某种形式的辅助方法,以便你可以从任何文件访问该功能。

let app = Application.testable.new({ (config, env, services) in
    try! App.configure(&config, &env, &services)
}) { (router) in

}

我建议将上述初始化放在一个便捷方法中,如此处所述

最后创建你的测试文件... 整个内容可能如下所示

import XCTest
import Vapor
import VaporTestTools


class GenericControllerTests: XCTestCase {
    
    var app: Application!
    
    // MARK: Linux
    
    static let allTests = [
        ("testHello", testHello),
        ("testPing", testPing),
        ("testNotFound", testNotFound),
        ("testHash", testHash)
    ]

    
    // MARK: Setup
    
    override func setUp() {
        super.setUp()
        
        app = Application.testable.newTestApp()
    }
    
    // MARK: Tests
    
    func testHello() {
        let req = HTTPRequest.testable.get(uri: "/hello")
        let r = app.testable.response(to: req)
        let res = r.response
        
        res.testable.debug()
        
        XCTAssertTrue(res.testable.has(statusCode: .ok), "Wrong status code")
        XCTAssertTrue(res.testable.has(contentType: "text/plain; charset=utf-8"), "Missing content type")
        XCTAssertTrue(res.testable.has(contentLength: 13), "Wrong content length")
        XCTAssertTrue(res.testable.has(content: "Hello, world!"), "Incorrect content")
    }
    
    func testPing() {
        let req = HTTPRequest.testable.get(uri: "/ping")
        let r = app.testable.response(to: req)
        let res = r.response
        
        // Print out info about the Response
        res.testable.debug()
        /*
        Debugging response:
        HTTP [1.1] with status code [200]
        Headers:
            Content-Type = application/json; charset=utf-8
            Content-Length = 15
            Date = Wed, 28 Feb 2018 00:52:02 GMT
        Content:
            Size: 15
            Media type: application/json; charset=utf-8
            Content:
        {"code":"pong"}
        */
        
        XCTAssertTrue(res.testable.has(statusCode: .ok), "Wrong status code")
        XCTAssertTrue(res.testable.has(contentType: "application/json; charset=utf-8"), "Missing content type")
        XCTAssertTrue(res.testable.has(contentLength: 15), "Wrong content length")
        XCTAssertTrue(res.testable.has(content: "{\"code\":\"pong\"}"), "Incorrect content")
    }
    
    func testNotFound() {
        let req = HTTPRequest.testable.get(uri: "/not-found")
        let r = app.testable.response(to: req)
        let res = r.response
        
        res.testable.debug()
        
        XCTAssertTrue(res.testable.has(statusCode: 404), "Wrong status code")
        XCTAssertFalse(res.testable.has(header: "Content-Type"), "Should not content type")
        XCTAssertTrue(res.testable.has(contentLength: 9), "Wrong content length")
        XCTAssertTrue(res.testable.has(content: "Not found"), "Incorrect content")
    }
    
    func testHash() {
        let req = HTTPRequest.testable.get(uri: "/hash/something")
        let r = app.testable.response(to: req)
        let res = r.response
        
        res.testable.debug()
        
        XCTAssertTrue(res.testable.has(statusCode: .ok), "Wrong status code")
        XCTAssertTrue(res.testable.has(contentType: "text/plain; charset=utf-8"), "Missing content type")
        XCTAssertTrue(res.testable.has(contentLength: 60), "Wrong content length")
    }
    
}

要查看更多实际示例,请参阅 VaporTestTools 的实际应用

自定义 Application 便捷方法

在以下示例 (Application+Testing.swift) 中,你可以看到 testable 属性的扩展,其中包含所有便捷方法。这将通过 Application.testable.newTestApp() 提供。

import Foundation
import App
import Vapor
import VaporTestTools


extension TestableProperty where TestableType: Application {
    
    public static func newTestApp() -> Application {
        let app = new({ (config, env, services) in
            try! App.configure(&config, &env, &services)
        }) { (router) in
            
        }
        return app
    }
    
}

用于测试的示例 Package.swift

你的整个 Package.swift 文件可能如下所示

// swift-tools-version:4.0
import PackageDescription

let package = Package(
    name: "MyApp",
    dependencies: [
        .package(url: "https://github.com/vapor/vapor.git", from: "3.0.0-beta.3.1.3"),
        .package(url: "https://github.com/LiveUI/VaporTestTools.git", from: "0.0.1")
    ],
    targets: [
        .target(
            name: "MyApp",
            dependencies: [
                "Vapor"
            ]
        ),
        .target(name: "Run", dependencies: [
            "MyApp"
            ]),
        .testTarget(name: "AppTests", dependencies: ["TestApp", "VaporTestTools"])
    ]
)

请注意 .testTarget(name: "AppTests", dependencies: ["TestApp", "VaporTestTools"]) 这一行,你在其中创建一个测试目标并包含 VaporTestTools

如果你认为该仓库值得,请不要忘记点赞!:)

祝你测试愉快!

Boost - 开源企业 AppStore

VaporTestTools 已作为 Boost 移动应用分发平台的一部分发布。

更多信息请访问 http://www.boostappstore.com

捆绑包中的其他组件包括

作者

Ondrej Rafaj (@rafiki270 在 Github, Twitter, LiveUI SlackVapor Slack)

许可

VaporTestTools 在 MIT 许可证下可用。有关更多信息,请参阅 LICENSE 文件。