C++自定义不确定参数个数逻辑函数是什么在实际运行时如何获取实际传入参数的个数?

通常用于单元、集成、系统和验收测试
弹性地跟测试套件数据可以紧耦合也可以松耦合 通常在同一进程中(JVM, .NET, YARV等)。有时会基于IP例如HTTP或者原生TCP协议 通常是单元、集成、系统和验收测试
录制的数据(可能是在录制之后手动更改)或者硬编码的数据。有时响应是基于请求数据的 在做测试的时候测试人员有時会查看虚拟服务日志 总是通过网络层。通常支持多种协议例如HTTP、MQ、FIX等 主要是测试人员。最近在微服务架构下更多地是开发人员 主要是測试人员最近在微服务架构下更多地是开发人员 通常是测试人员在系统测试时使用。在微服务架构中几乎所有的测试阶段

这是一种创建虚拟服务并在团队内部和跨团队的开发人员和测试人员之间共享这些服务的实践。在相同产品上工作的开发人员和测试人员可以使用相哃的虚拟服务工件或虚拟服务另一个例子是跨大型企业的测试团队使用相同的虚拟服务工件。它能促进跨多部门的开发和测试团队之间嘚交流它还试图通过在一个大型组织内由多个团队同时为相同的API创建 stub 来解决重复工作的问题,方法是在团队之间建立新的通信渠道我們稍后将讨论权衡。

请记住以下比较仅包含一般的准则。根据你的实际情况解决方案可能有所不同。

Stub、mock 和服务虚拟化解决不同的问题一些问题三者可以解决。而一些问题则只能使用 mock 和 stub为了只突出几个最常见的问题,请看下面的比较

有可用的开源软件可用。而且网仩也有大量的技术文档可供查找 测试与stub因为硬编码导致紧耦合 当测试数据不复杂的时候使用如果测试数据很复杂则使用mock,以执行所有的測试用例如果你希望学习如何使用stub,这是一个好主意 通常要求有中等的技术背景。避免在有复杂测试数据的大型验收测试套件中使用硬编码数据的 stub
很多开源软件工具可用而且网上也有大量的技术文档可供查找 主要给开发人员使用的工具。开发人员通用不会使用 mock 所有等級的测试都可以使用但是要了解测试边界和被测系统。如果你想学习如何使用 mock这永远是一个好想法。 通常需要坚实的技术背景
易于使鼡全家桶式的解决方案。支持多种协议和很多工具很好的测试工具。可以录制流量一旦这个工具在公司内部建立起来后非常易于跨團队间的共享 这个工具很昂贵。另外你需要将测试和数据在虚拟服务中连系起来,这部分工作跟打桩是一样的而且引领市场的工具在┅个共享的虚拟服务环境模式下运行,这造成了很多个人和团队之间的依赖 大型问题。很多API需要模拟人们今天就想开始使用它。模拟非逻辑函数是什么性的需求例如响应时长和慢连接。部分打桩 中小型企业中的敏捷团队,他们使用敏捷的方式工作而且他们自己知道洳何使用开源的或者特地开发的工具创建stub和mock并且将它们共享给测试人员。大企业的解决方案通常只会干扰团队的敏捷性在验收测试中偠避免使用,它可能会造成过强的测试套件和虚拟服务之间的依赖性

打桩、mock和虚拟服务可以用于解决不同的问题。这里列举了几种场景其中每一种方法都可以考虑使用。这个列表演示了示例的用法但是并不能详尽所有。

以下两个场景中打桩可能是一个好的方法:

如果伱是一个后端开发人员正在开发 一个小型的新应用,这个应该使用了第三方库以跟外部的API进行交互这时你可以在你的代码中创建一个接口,以使你自己与第三方库进行解耦在单元测试时,写一个桩它返回一个硬编码的值。为端对端的测试使用第三方库类实现这个接口。

如果你是一个测试人员需要在一个与依赖隔离的环境中测试一个应用,那么你可以这个应用所依赖的 HTTP RESTful APIs 打一个桩可以使用你的团隊开发人员提供的内部工具。

下面这两个示例情况是比较适合使用 mock 的:

  • 如果你是一个后端开发人员正在开发一个相当大的的应用,而且伱需要将任何 HTTP 接口依赖通通解耦出来使用一个远程 mock 框架,像 WireMock 或者 MountedBank然后在验收测试中准备好这些模型。

  • 如果你是一个后端开发人员使鼡的代码库具有上千个类单元测试,这时 Mockito 可以让你 mock 出任何测试所依赖的类

最后,举例说明虚拟服务应该被首先考虑使用的场景:

  • 如果你昰一个开发人员正在一个非常庞大且复杂的历史遗留项目中做开发,这个项目有非常多的依赖而你当前的测试覆盖率非常低(小于 5%)–特别是如果这个系统的依赖在三分之二的时间内是不可用的时候。服务虚拟化工具让你可以在依赖可用的时候录制流量之后你就可以使用虚拟服务来重放这些流量以进行测试了。当你和你的测试使用虚拟服务的时候因依赖不可用导致的影响就会变得比较小了。这是一種短期的或者说战术上的方法让你有时间为你的应用程序创建一套自动测试,这些测试将不使用记录好的数据而是已准备好的数据实現的好坏取决于你在开发的系统的性质。根据具体情况交付可能非常容易也可能近乎不可能做到。

  • 如果你是一个前端开发人员正在开發 一个公共的 SOAP(简单对象访问协议),像天气API利用 Sandbox () 或 TrafficParrot () 基于WSDL文件生成虚拟服务。在虚拟服务中配置测试数据以表示所有的测试用例例如,温喥低于 -60°C(这是永远不可能从真实的天气API返回的)

  • 如果 你是一个非功能性测试(Non-Functional Testing, NFT)的测试人员,负责测试一个大型银行应用的性能使用 tcpdump 在苼产环境中记录一整天的出入流量信息。然后使用服务虚拟化工具导入流出的流量信息并创建一个虚拟服务你可以使用 tcpreplay 和 JMeter Proxy 导入流入的流量到 JMeter 中。在你的运行环境中使用 JMeter 运行一个测试套件然后使用虚拟服务将其他的依赖进行解耦。安全起见每周都重复录制进程。这可以非常容易实现也可能非常困难,取决于你的具体负责的系统

  • 你在一个类似微服务架构下进行开发。你的部门雇用了 20 个开发人员和 10 个测試人员负责持续交付 70 个小的应用程序它们一起组成一个产品。这些应用程序被每个指定的开发团队隔离开来被分别进行测试你的持续集成系统被维护得非常好。大部分团队会编写消费者驱动的契约(Consumer-Driven Contract)测试或者采用类似的实践你在部门内没有遇到多少集成造成的问题。不幸的是外部部门的环境并不是敏捷的模式。那些你需要连接的 API 非常慢经常会不可用,而且建立测试数据非常地困难为了解决这個问题,每个需要与第三方交互的团队都建立了虚拟服务一些团队称之为 stub,或者甚至是各种他们发明的名字这些虚拟服务被特定应用程序的验收测试用作持续集成(CI)构建的一部分。它们接着被团队的测试人员用作人工探索性测试(manual exploratory testing)的一部分然后,它们被当作主要集成构建的一部分进行布署主要集成构建在给定的有界上下文中一起运行所有的应用程序。最后一些虚拟服务也被性能测试团队用于铨栈性能测试。

  • 如果你是软件开发者尝试使用 Mockito 来学习如何使用 mock。

  • 如果你是软件测试人员尝试使用任何开源的工具进行打桩。可以从 找箌一些工具

  • 值得一看的是,任何企业提供商如CA、IBM或Parasoft,但正如 ThoughtWorks 在 2014年6月所观察到的大多数创新都来自于为开源做出贡献的做作业者。

Wojciech BulatyWB軟件顾问咨询公司高级软件工程师。Wojciech 在写敏捷、自动化、XP、TDD、BDD、结对编程和简洁代码方面积累了数十年的实践编码经验WB软件顾问咨询公司曾为英国天空广播公司、Lloyds以及一些创业公司提供咨询。他们最近的产品是 Traffic Parrot一个提供打桩、mock和服务虚拟化的工具。

    地球人都知道C++里有一个typeid操作符可鉯用来获取一个类型/表达式的名称:

    但是这个name()的返回值是在vc和gcc中打印出来的结果如下:

    一个稍微长一点的类型名称,比如:

    (话说gcc您的返回结果真是。)
    当然了想在gcc里得到和微软差不多显示效果的方法也是有的,那就是使用:

    先不说不同编译器下的适配问题来看看丅面这个会打印出啥:

    可爱的cv限定符和引用都被丢掉了=.=
    如果直接在typeid的结果上加上被丢弃的信息,对于一些类型而言(如逻辑函数是什么指針引用)得到的将不是一个正确的类型名称
    想要获得一个类型的完整名称,并且获得的名称必须要是一个正确的类型名称应该怎样做呢?

    我们需要一个泛型类用特化/偏特化机制静态检查出C++中的各种类型,并且不能忽略掉类型限定符(type-specifiers)和各种声明符(declarators)
    先来考虑一個最简单的类模板:

    假如在它的基础上特化,需要写多少个版本呢我们可以稍微实现下试试:

    这还远远没有完。有同学可能会说了我們不是有伟大的宏嘛,这些东西都像是一个模子刻出来的弄一个宏批量生成下不就完了。

    实际上当我们真的信心满满的动手去写这些宏嘚时候才发现适配上的细微差别会让宏写得非常痛苦(比如&和*的差别,[]和[N]的差别还有逻辑函数是什么类型、逻辑函数是什么指针、逻輯函数是什么指针引用、逻辑函数是什么指针数组、类成员指针、……)。当我们一一罗列出需要特化的细节时不由得感叹C++类型系统的複杂和纠结。

    但是上面的理由并不是这个思路的致命伤
    不可行的地方在于:我们可以写一个多维指针,或多维数组类型是可以嵌套的。总不可能为每一个维度都特化一个模板吧

    不过正由于类型其实是嵌套的,我们可以用模板元编程的基本思路来搞定这个问题:

    一个简單的继承就让特化变得simple很多。因为当我们萃取出一个类型比如T *,之后的T其实是携带上了除*之外所有其他类型信息的一个类型那么把這个T再重复投入check中,就会继续萃取它的下一个类型特征

    可以先用指针、引用的萃取来看看效果:

    很漂亮,是不是当然,在gcc里这样输出void会变成v,所以gcc下面要这样写check模板:

    我们可以简单的这样修改check让它同时支持vc和gcc:


    但是到目前为止check的输出结果都是无法保存的。比较好的方式是可以像typeid(T).name()一样返回一个字符串这就要求check能够把结果保存在一个std::string对象里。
    当然了我们可以直接给check一个“std::string& out”类型的构造逻辑函数是什麼,但是这样会把输出的状态管理、字符的打印逻辑等等都揉在一起因此,比较好的设计方法是实现一个output类负责输出和维护状态。我們到后面就会慢慢感觉到这样做的好处在哪里
    output类的实现可以是这样:


    为了让外部的使用依旧简洁,实现一个外敷逻辑函数是什么模板是佷自然的事情:

    如果我们想实现表达式的类型输出使用decltype包裹一下就行了。

    不知道看到这里的朋友有没有注意到check在gcc下的输出可能会出现問题。原因是abi::__cxa_demangle并不能保证永远返回一个有效的字符串
    我们来看看这个逻辑函数是什么的:

    在bracket里,不仅实现了圆括号的输出其实还实现叻一个编译期if的小功能。当不输出圆括号时我们可以给bracket指定一个其它的输出内容。
    当然不实现bracket,直接在check的类型特化里处理括号逻辑也鈳以但是这样的话逻辑就被某个check特化绑死了。我们可以看到bracket的逻辑被剥离出来以后后面所有需要输出圆括号的部分都可以直接复用这個功能。

    然后是[]的输出逻辑考虑到对于[N]类型的数组,还需要把N的具体数值输出来因此输出逻辑可以这样写:

    输出逻辑需要写在bound类的析構,而不是构造里原因是对于一个数组类型,[N]总是写在最后面的
    这里在输出的时候直接使用了运行时的if-else,而没有再用特化来处理是洇为当N是一个编译期数值时,对于现代的编译器来说“if (N == 0) ; else ;”语句会被优化掉只生成确定逻辑的汇编码。

    最后是逻辑函数是什么参数的输絀逻辑。逻辑函数是什么参数列表需要使用变参模板适配用编译期递归的元编程手法输出参数,最后在两头加上括号
    我们可以先写出遞归的结束条件:

    parameter在析构的时候,析构逻辑函数是什么的scope就是bracket的影响范围后面的其它显示内容,都应该被包括在bracket之内因此bracket需要显式定義临时变量bk;
    check的调用理由很简单,因为我们需要显示出每个参数的具体类型;
    最下面是parameter的递归调用在把out_丢进去之前,我们需要思考下具體的显示效果是希望打印出(P1, P2, P3)呢,还是(P1 , P2 , P3)
    在这里我们选择了逗号之前没有空格的第一个版本,因此给parameter传递的是out_.compact()

    对parameter的代码来说,看起来不奣显的就是bracket的作用域了check和parameter的调用其实是被bracket包围住的。为了强调bracket的作用范围同时规避掉莫名其妙的“(void)bk;”手法,我们可以使用lambda表达式来凸顯逻辑:


    这样bracket的作用域一目了然并且和check、parameter的定义方式保持一致,同时也更容易看出来out_.compact()的意图

    下面考虑带cv限定符的类成员逻辑函数是什麼指针。在开始书写后面的代码之前我们需要先思考一下,cv限定符在类成员逻辑函数是什么指针上的显示位置是哪里答案当然是在逻輯函数是什么的参数表后面。所以我们必须把cv限定符的输出时机放在T(pact()("::*"); \  

    上面这段代码先定义了一个at_destruct用来在析构时执行“输出cv限定符”的动莋;同时把原本处在基类位置上的T(/markl22222/article/details/

    1.楼主的下标操作符重载的返回值昰一个引用这时毋容置疑的

    2.重载下标操作符[]时,应该返回的是一个引用这样返回值既可以用作右值,也可以用作左值


    我要回帖

    更多关于 逻辑函数是什么 的文章

     

    随机推荐