关于测试

测试类型

测试代码是我们的好朋友(测试人员也是). 它可以使我们写代码的时候更自信, 不必过分担心不小心影响到其他功能. 测试可以帮助我们.

一些常规开发过程中的:
1. End to end test
1. Integration test
1. Unit test

和一些发布后进行的:
1. Smoke/Sanity test
1. Regression test

以及一些性能测试.

测试什么

从后端程序员的视角来看, 日常开发更关注于Unit test和Integration test. 通过一些测试组件, 覆盖各种条件.

单元测试

单元测试主要测试代码片段, 通常是方法级别的测试, 测试各种条件的输入下, 方法可以得到意料之类的结果. 测试覆盖率应该尽可能的高, 边界条件要尽可能覆盖, 这是比较理想的情况..
写可以测试的代码, 代码逻辑混乱, 方法体过大, 参数过多都会让测试变得困难. 所以测试的另一个好处就是让代码结构合理一些, 因为这些代码要可以测试, 会自然而然的被”优化”.

所有的测试都可以被抽象为下面的模型.

3A:
1. Arrange , 安排起来.. // var testObject = new TestObject();
1. Act , 执行 // var result = testObject.MethodA();
1. Assert , 断言 // Assert.AreEqual(true, result);

集成测试

集中在测试后端接口, 构造一个client, 发起请求, 验证API的相应状态与结果, 以及一些中间数据的状态. 相对来说每个步骤都会复杂一些, 虽然也是上面的3A模型.

//var server = new TestServer();
//var client = server.CreateClient();

//var response = await client.GetAsync(“…”);

//Assert.AreEqual(200, response.StatusCode);
//Assert.AreEqual(“testContent”, response.Content)

对于不同版本的aspnet core版本, 实现方式略有不同, 不过方式都是为了创建In-Memory server, 然后访问接口了.

集成测试 aspnet core 1.1

可以使用TestServer class来实现,TEntryPointStartup后者子类. 定制不太方便, 最近再研究下怎么控制.

            _server = new TestServer(new WebHostBuilder()
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseStartup<TEntryPoint>());
            _client = _server.CreateClient(); //get client

集成测试 aspnet core 2.2+

MSDN有详细的文档, 不做胶水程序员了! 值得注意的是开放了WebApplicationFactory.ConfigureWebHost, 可以方便的定制services.

            _factory = new CustomWebApplicationFactory<Startup>();
            _factory.WithWebHostBuilder(builder =>
            {
                var mockMailService = A.Fake<IMailService>();
                A.CallTo(() => mockMailService.SendActivationEmail(A<User>.Ignored)).Returns(Task.CompletedTask);
                builder.ConfigureServices(services =>
                {
                    services.Replace(new ServiceDescriptor(typeof(IMailService), sp => mockMailService,
                        ServiceLifetime.Scoped));
                });
            });

            //...
            var client = _factory.CreateClient();

疫情见闻与思考

# 疫情见闻与思考
这场瘟疫如同虫族入侵一样, 席卷全球,迅速而无情. 商人休市, 工人停工, 学生停课, 整个社会因此停摆. 各个单元(小区/市/省/国)按照需求限制出入. 它打破了无数人的计划, 留学/旅游/结婚等. 各个国家都因此遭受不同程度的损失, 2020Q1的GDP基本都是负增长, 各国政府为了稳固形式, 鼓吹民族主义, 有那么点末日景象了.


幸运的是, 如同大部分剧情, 黑暗的尽头是黎明而不是无尽的黑暗. 前几天的授勋仪式宣告了中国的疫情抗战阶段性胜利, 感谢为此付出的每一个人, 有些人甚至付出了生命. 疫情刚开始的时候每天看着感染人数攀升时那种绝望的感觉, 无尽的绝望, 再也不想体验了.这次国内应对疫情强大的动员能力让人惊叹, 从武汉封闭开始, 我老家的村子也几乎同步封闭, 禁止车辆出入.


感染者死亡数字现在还在不断增加, 这个外人看来只是个数字, 对于每个逝者的家庭来说, 是天大的不幸. 乐观虽然能改变心态, 但是改变不了客观事实, 事情还是需要行动起来才能解决. 幸好那些”自由”的国家最近也行动起来了, 是不是有些迟了? 


想想2-3月时外媒的狂欢, 如: 这个疫情完全是人祸, 是政府的锅, 黄种人才容易感染, 中药完全无效 等等, 疫情感染到自己国家后才哑火. 媒体始终是政党的喉舌, 指望一个外国的媒体只说中国的好话而不夹带私货, 想peach, 至少很难. 这些广大民众可以接受到的媒体存在的意义就是为某个团体服务, 做到完全中立恐怕不可能. 我们的媒体当然也一样, 所以要了解一个东西, 要多换几个地方综合起来分析.


(未完)

divide zero

在常规的数字运算中,除以零在代码里是不合法的,在不同的编程语言就不同的处理。比如在C#中,在编译时会提示CS0020: Division by constant zero, 在运行时会抛出异常: System.DivideByZeroException: ‘Attempted to divide by zero.’。

在Javascript中,有些微妙,区分处理了0和其他数字做为除数。

这个与数学里面极限1/x,x->0时的极限,但是左极限和右极限不相等,一个正无穷,一个是负无穷, 0点极限不存在。虽然JS结果不正确,不过这个可以避免一些麻烦(比如上面C#的异常)。

check time range overlap

目前维护的系统里面有一个关于日期与其他现有日期数据重叠的校验,之前的写法有点乱,顺手google了一把,结果发现一个很巧妙的校验方法,以及一些关于这个时间重叠的一些资料。

就是下面这个了,比之前版本的代码4个if要看起来舒服很多

(StartA <= EndB) and (EndA >= StartB)

证明部分就不抄了,利用了集合论的一个公式:

非( p 或 q )等价于( 非 p )且( 非 q )。

那么如果要区分重叠的类型是如何呢, Allen’s interval algebra 定义了13种2个区间的关系。

另外, 这个stackoverflow的问题下面还列举了一些对上面的关系的扩展的库, Time Period Library,希望后面可以用到这个库。 感谢开源软件。

refs:

https://stackoverflow.com/questions/325933/determine-whether-two-date-ranges-overlap

https://en.wikipedia.org/wiki/Allen%27s_interval_algebra

https://www.codeproject.com/Articles/168662/Time-Period-Library-for-NET

jhipster正在支持.NET Core

jhipster 正在支持 .NET Core

jhipster 全名Java Hipster Java潮人,是一个Java的代码生成器,对于一些内容不多,可以使用这个工具快速创建。

集成了目前流行的各种前端框架,服务端支持多种数据库,以及对分布式,微服务等支持,包含CI/CD功能。

现在正在计划支持.NET Core, 官方已经有个可以运行的sample项目了! 项目链接

我要积极PR.