wmproxy
已用Rust
实现http/https
代理, socks5
代理, 反向代理, 静态文件服务器,四层TCP/UDP转发,七层负载均衡,内网穿透,后续将实现websocket
代理等,会将实现过程分享出来,感兴趣的可以一起造个轮子
国内: https://gitee.com/tickbh/wmproxy
github: https://github.com/tickbh/wmproxy
在程序中,通常会写一些自动化测试的功能,来保证我们的代码正确的执行符合预期的效果,随着时间的变化,当代码变动的数据越来越多时,保证能实时的测试确保整个系统高概率的正常运转,不会因为改一个Bug而产生另一个Bug
Rust中的测试分为两个部分
文档测试通常在函数前面或者类前面,通过文档测试来保证该函数的运行能符合我们的预期,通常
/// ```
包围,以下为测试示例,如果仅仅以///
开头那么测试
RUST/// 测试vec的大小
///
/// use std::vec::Vec;
///
/// let mut vec = Vec::new();
/// assert_eq!(vec.len(), 0);
/// vec.push(1);
/// assert_eq!(vec.len(), 1);
fn show_test() {
}
此时我们运行cargo test
可以看的到如下输出:
running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
此时并不能识别我们的文档测试用例,那么我们在代码前后加上/// ```
再来运行
RUST/// 测试vec的大小
///
/// ```
/// use std::vec::Vec;
///
/// let mut vec = Vec::new();
/// assert_eq!(vec.len(), 0);
/// vec.push(1);
/// assert_eq!(vec.len(), 1);
/// ```
fn show_test() {
}
将得到如下输出
running 1 test test src\lib.rs - show_test (line 3) ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.22s
此时测试通过自动化模块
RUSTfn str_len(s: &str) -> usize {
s.len()
}
async fn str_len_async(s: &str) -> usize {
// 做些异步的事情
s.len()
}
#[cfg(test)]
#[allow(non_snake_case)]
mod tests {
use super::*;
#[test]
fn test_str_len() {
assert_eq!(str_len("x5ff"), 4);
}
此时运行测试结果很完美的通过测试
running 1 test test tests::test_str_len ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
当我们将str_len
->str_len_async
时,那么他提示我们
error[E0369]: binary operation `==` cannot be applied to type `impl Future<Output = usize>` --> src\lib.rs:29:9 | 29 | assert_eq!(str_len_async("x5ff"), 4); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | impl Future<Output = usize> | {integer} | = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `impl Future<Output = usize>` doesn't implement `Debug` --> src\lib.rs:29:9 | 29 | assert_eq!(str_len_async("x5ff"), 4); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `impl Future<Output = usize>` cannot be formatted using `{:?}` because it doesn't implement `Debug` | = help: the trait `Debug` is not implemented for `impl Future<Output = usize>` = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) Some errors have detailed explanations: E0277, E0369. For more information about an error, try `rustc --explain E0277`.
因为异步返回的结果是Future,所以我们无法通过编译。
那么异步的函数如何通过自动化测试呢?
我们尝试将测试函数改成异步
mod tests { use super::*; #[test] async fn test_str_len() { assert_eq!(str_len_async("x5ff").await, 4); } }
编译器提示我们,因为编译器暂时不能支持异步的测试
error: async functions cannot be used for tests --> src\lib.rs:28:5 | 28 | async fn test_str_len() { | ^---- | | | _____`async` because of this | | 29 | | assert_eq!(str_len_async("x5ff").await, 4); 30 | | } | |_____^
此处讲的依赖tokio
的runtime
,其它的异步为类似。
#[tokio::test]
来完成异步测试
首先我们依赖:TOML[dependencies]
tokio = { version = "*", features = [
"macros",
"test-util",
] }
tokio-test = "0.4.3"
此刻我们将代码改写成:
RUST#[cfg(test)]
#[allow(non_snake_case)]
mod tests {
use super::*;
#[tokio::test]
async fn test_str_len() {
assert_eq!(str_len_async("x5ff").await, 4);
}
}
此时运行cargo test
,将正常的运行通过
此方法运用的是通过同步函数中运行一个runtime来运行异步函数
以下是我们的宏定义及调用
macro_rules! aw { ($e:expr) => { tokio_test::block_on($e) }; } #[test] fn test_str_len_async_2() { assert_eq!(aw!(str_len_async("x5ff")), 4); }
此时运行cargo test
,将正常的运行通过
running 2 tests test tests::test_str_len_async_2 ... ok test tests::test_str_len ... ok test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
但是此时如果是局部测试,该方法有另一个好处,编辑器的识别度较高,能更好的显示支持
测试是编程中不可缺少的伙伴,他可以让我们更早的发现问题解决问题,编写测试用例可能看起来会慢一些,但是对后期可能潜在的Bug的排查会节省大量的时间。
点击 [关注],[在看],[点赞] 是对作者最大的支持
本文作者:问蒙服务框架
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!