广州网站建设公司万齐网络科技html网站免费模板下载

diannao/2025/10/25 21:36:56/文章来源:
广州网站建设公司万齐网络科技,html网站免费模板下载,地方网站改版方案,中小型网站建设报价本章概要 测试驱动开发 测试驱动 vs 测试优先 日志 日志信息日志等级 测试驱动开发 之所以可以有测试驱动开发#xff08;TDD#xff09;这种开发方式#xff0c;是因为如果你在设计和编写代码时考虑到了测试#xff0c;那么你不仅可以写出可测试性更好的代码#xff…本章概要 测试驱动开发 测试驱动 vs 测试优先 日志 日志信息日志等级 测试驱动开发 之所以可以有测试驱动开发TDD这种开发方式是因为如果你在设计和编写代码时考虑到了测试那么你不仅可以写出可测试性更好的代码而且还可以得到更好的代码设计。 一般情况下这个说法都是正确的。 一旦我想到“我将如何测试我的代码”这个想法将使我的代码产生变化并且往往是从“可测试”转变为“可用”。 纯粹的 TDD 主义者会在实现新功能之前就为其编写测试这称为测试优先的开发。 我们采用一个简易的示例程序来进行说明它的功能是反转 String 中字符的大小写。 让我们随意添加一些约束String 必须小于或等于30个字符并且必须只包含字母空格逗号和句号(英文)。 此示例与标准 TDD 不同因为它的作用在于接收 StringInverter 的不同实现以便在我们逐步满足测试的过程中来体现类的演变。 为了满足这个要求将 StringInverter 作为接口 // validating/StringInverter.java package validating;interface StringInverter {String invert(String str); }现在我们通过可以编写测试来表述我们的要求。 以下所述通常不是你编写测试的方式但由于我们在此处有一个特殊的约束我们要对 **StringInverter **多个版本的实现进行测试为此我们利用了 JUnit5 中最复杂的新功能之一动态测试生成。 顾名思义通过它你可以使你所编写的代码在运行时生成测试而不需要你对每个测试显式编码。 这带来了许多新的可能性特别是在明确地需要编写一整套测试而令人望而却步的情况下。 JUnit5 提供了几种动态生成测试的方法但这里使用的方法可能是最复杂的。 **DynamicTest.stream() **方法采用了 对象集合上的迭代器 (versions) 这个迭代器在不同组的测试中是不同的。 迭代器生成的对象可以是任何类型但是只能有一种对象生成因此对于存在多个不同的对象类型时必须人为地将它们打包成单个类型。Function它从迭代器获取对象并生成描述测试的 String 。Consumer它从迭代器获取对象并包含基于该对象的测试代码。 在此示例中所有代码将在 testVersions() 中进行组合以防止代码重复。 迭代器生成的对象是对 DynamicTest 的不同实现这些对象体现了对接口不同版本的实现 import org.junit.jupiter.api.*;import java.util.*; import java.util.function.*; import java.util.stream.*;import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue;class DynamicStringInverterTests {// Combine operations to prevent code duplication:StreamDynamicTest testVersions(String id,FunctionStringInverter, String test) {ListStringInverter versions Arrays.asList(new Inverter1(), new Inverter2(),new Inverter3(), new Inverter4());return DynamicTest.stream(versions.iterator(),inverter - inverter.getClass().getSimpleName(),inverter - {System.out.println(inverter.getClass().getSimpleName() : id);try {if (test.apply(inverter) ! fail)System.out.println(Success);} catch (Exception | Error e) {System.out.println(Exception: e.getMessage());}});}String isEqual(String lval, String rval) {if (lval.equals(rval))return success;System.out.println(FAIL: lval ! rval);return fail;}BeforeAllstatic void startMsg() {System.out.println( Starting DynamicStringInverterTests );}AfterAllstatic void endMsg() {System.out.println( Finished DynamicStringInverterTests );}TestFactoryStreamDynamicTest basicInversion1() {String in Exit, Pursued by a Bear.;String out eXIT, pURSUED BY A bEAR.;return testVersions(Basic inversion (should succeed),inverter - isEqual(inverter.invert(in), out));}TestFactoryStreamDynamicTest basicInversion2() {return testVersions(Basic inversion (should fail),inverter - isEqual(inverter.invert(X), X));}TestFactoryStreamDynamicTest disallowedCharacters() {String disallowed ;-_()*^%$#!~0123456789;return testVersions(Disallowed characters,inverter - {String result disallowed.chars().mapToObj(c - {String cc Character.toString((char) c);try {inverter.invert(cc);return ;} catch (RuntimeException e) {return cc;}}).collect(Collectors.joining());if (result.length() 0)return success;System.out.println(Bad characters: result);return fail;});}TestFactoryStreamDynamicTest allowedCharacters() {String lowcase abcdefghijklmnopqrstuvwxyz ,.;String upcase ABCDEFGHIJKLMNOPQRSTUVWXYZ ,.;return testVersions(Allowed characters (should succeed),inverter - {assertEquals(inverter.invert(lowcase), upcase);assertEquals(inverter.invert(upcase), lowcase);return success;});}TestFactoryStreamDynamicTest lengthNoGreaterThan30() {String str xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;assertTrue(str.length() 30);return testVersions(Length must be less than 31 (throws exception),inverter - inverter.invert(str));}TestFactoryStreamDynamicTest lengthLessThan31() {String str xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;assertTrue(str.length() 31);return testVersions(Length must be less than 31 (should succeed),inverter - inverter.invert(str));} }在一般的测试中你可能认为在进行一个结果为失败的测试时应该停止代码构建。 但是在这里我们只希望系统报告问题但仍然继续运行以便你可以看到不同版本的 StringInverter 的效果。 每个使用 **TestFactory ** 注释的方法都会生成一个 DynamicTest 对象的 Stream通过 testVersions() 每个 JUnit 都像常规的 **Test ** 方法一样执行。 现在测试都已经准备好了我们就可以开始实现 **StringInverter **了。 我们从一个仅返回其参数的假的实现类开始 // validating/Inverter1.java package validating; public class Inverter1 implements StringInverter {public String invert(String str) { return str; } }接下来我们实现反转操作 // validating/Inverter2.java package validating; import static java.lang.Character.*; public class Inverter2 implements StringInverter {public String invert(String str) {String result ;for(int i 0; i str.length(); i) {char c str.charAt(i);result isUpperCase(c) ?toLowerCase(c) :toUpperCase(c);}return result;} }现在添加代码以确保输入不超过30个字符 // validating/Inverter3.java package validating; import static java.lang.Character.*; public class Inverter3 implements StringInverter {public String invert(String str) {if(str.length() 30)throw new RuntimeException(argument too long!);String result ;for(int i 0; i str.length(); i) {char c str.charAt(i);result isUpperCase(c) ?toLowerCase(c) :toUpperCase(c);}return result;} }最后我们排除了不允许的字符 // validating/Inverter4.java package validating; import static java.lang.Character.*; public class Inverter4 implements StringInverter {static final String ALLOWED abcdefghijklmnopqrstuvwxyz ,. ABCDEFGHIJKLMNOPQRSTUVWXYZ;public String invert(String str) {if(str.length() 30)throw new RuntimeException(argument too long!);String result ;for(int i 0; i str.length(); i) {char c str.charAt(i);if(ALLOWED.indexOf(c) -1)throw new RuntimeException(c Not allowed);result isUpperCase(c) ?toLowerCase(c) :toUpperCase(c);}return result;} }你将从测试输出中看到每个版本的 Inverter 都几乎能通过所有测试。 当你在进行测试优先的开发时会有相同的体验。 DynamicStringInverterTests.java 仅是为了显示 TDD 过程中不同 StringInverter 实现的开发。 通常你只需编写一组如下所示的测试并修改单个 StringInverter 类直到它满足所有测试 // validating/tests/StringInverterTests.java package validating; import java.util.*; import java.util.stream.*; import org.junit.jupiter.api.*; import static org.junit.jupiter.api.Assertions.*;public class StringInverterTests {StringInverter inverter new Inverter4();BeforeAllstatic void startMsg() {System.out.println( StringInverterTests );}Testvoid basicInversion1() {String in Exit, Pursued by a Bear.;String out eXIT, pURSUED BY A bEAR.;assertEquals(inverter.invert(in), out);}Testvoid basicInversion2() {expectThrows(Error.class, () - {assertEquals(inverter.invert(X), X);});}Testvoid disallowedCharacters() {String disallowed ;-_()*^%$#!~0123456789;String result disallowed.chars().mapToObj(c - {String cc Character.toString((char)c);try {inverter.invert(cc);return ;} catch(RuntimeException e) {return cc;}}).collect(Collectors.joining());assertEquals(result, disallowed);}Testvoid allowedCharacters() {String lowcase abcdefghijklmnopqrstuvwxyz ,.;String upcase ABCDEFGHIJKLMNOPQRSTUVWXYZ ,.;assertEquals(inverter.invert(lowcase), upcase);assertEquals(inverter.invert(upcase), lowcase);}Testvoid lengthNoGreaterThan30() {String str xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;assertTrue(str.length() 30);expectThrows(RuntimeException.class, () - {inverter.invert(str);});}Testvoid lengthLessThan31() {String str xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;assertTrue(str.length() 31);inverter.invert(str);} }你可以通过这种方式进行开发一开始在测试中建立你期望程序应有的所有特性然后你就能在实现中一步步添加功能直到所有测试通过。 完成后你还可以在将来通过这些测试来得知或让其他任何人得知当修复错误或添加功能时代码是否被破坏了。 TDD的目标是产生更好更周全的测试因为在完全实现之后尝试实现完整的测试覆盖通常会产生匆忙或无意义的测试。 测试驱动 vs 测试优先 虽然我自己还没有达到测试优先的意识水平但我最感兴趣的是来自测试优先中的“测试失败的书签”这一概念。 当你离开你的工作一段时间后重新回到工作进展中甚至找到你离开时工作到的地方有时会很有挑战性。 然而以失败的测试为书签能让你找到之前停止的地方。 这似乎让你能更轻松地暂时离开你的工作因为不用担心找不到工作进展的位置。 纯粹的测试优先编程的主要问题是它假设你事先了解了你正在解决的问题。 根据我自己的经验我通常是从实验开始而只有当我处理问题一段时间后我对它的理解才会达到能给它编写测试的程度。 当然偶尔会有一些问题在你开始之前就已经完全定义但我个人并不常遇到这些问题。 实际上可能用“面向测试的开发 ( Test-Oriented Development )”这个短语来描述编写测试良好的代码或许更好。 日志 日志信息 在调试程序中日志可以是普通状态数据用于显示程序运行过程例如安装程序可能会记录安装过程中采取的步骤存储文件的目录程序的启动值等。 在调试期间日志也能带来好处。 如果没有日志你可能会尝试通过插入 println() 语句来打印出程序的行为。 本书中的一些例子使用了这种技术并且在没有调试器的情况下下文中很快就会介绍这样一个主题它就是你唯一的工具。 但是一旦你确定程序正常运行你可能会将 println() 语句注释或者删除。 然而如果你遇到更多错误你可能又需要运行它们。因此如果能够只在需要时轻松启用输出程序状态就好多了。 程序员在日志包可供使用之前都只能依赖 Java 编译器移除未调用的代码。 如果 debug 是一个 **static final boolean **你就可以这么写 if(debug) {System.out.println(Debug info); }然后当 **debug **为 **false **时编译器将移除大括号内的代码。 因此未调用的代码不会对运行时产生影响。 使用这种方法你可以在整个程序中放置跟踪代码并轻松启用和关闭它。 但是该技术的一个缺点是你必须重新编译代码才能启用和关闭跟踪语句。因此通过更改配置文件来修改日志属性从而起到启用跟踪语句但不用重新编译程序会更方便。 业内普遍认为标准 Java 发行版本中的日志包 (java.util.logging) 的设计相当糟糕。 大多数人会选择其他的替代日志包。如 Simple Logging Facade for Java(SLF4J) ,它为多个日志框架提供了一个封装好的调用方式这些日志框架包括 java.util.logging logback 和 **log4j **。 SLF4J 允许用户在部署时插入所需的日志框架。 SLF4J 提供了一个复杂的工具来报告程序的信息它的效率与前面示例中的技术几乎相同。 对于非常简单的信息日志记录你可以执行以下操作 import org.slf4j.*;public class SLF4JLogging {private static Logger log LoggerFactory.getLogger(SLF4JLogging.class);public static void main(String[] args) {log.info(hello logging);} }日志输出中的格式和信息甚至输出是否正常或“错误”都取决于 SLF4J 所连接的后端程序包是怎样实现的。 在上面的示例中它连接到的是 logback 库通过本书的 build.gradle 文件并显示为标准输出。 日志系统会检测日志消息处所在的类名和方法名。 但它不能保证这些名称是正确的所以不要纠结于其准确性。 日志等级 SLF4J 提供了多个等级的日志消息。下面这个例子以“严重性”的递增顺序对它们作出演示 import org.slf4j.*;public class SLF4JLevels {private static Logger log LoggerFactory.getLogger(SLF4JLevels.class);public static void main(String[] args) {log.trace(Hello);log.debug(Logging);log.info(Using);log.warn(the SLF4J);log.error(Facade);} }你可以按等级来查找消息。 级别通常设置在单独的配置文件中因此你可以重新配置而无需重新编译。 配置文件格式取决于你使用的后端日志包实现。 如 logback 使用 XML !-- validating/logback.xml -- ?xml version1.0 encodingUTF-8? configurationappender nameSTDOUTclassch.qos.logback.core.ConsoleAppenderencoderpattern %d{yyyy-MM-ddTHH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n/pattern/encoder/appenderroot levelTRACEappender-ref refSTDOUT //root /configuration你可以尝试将 **root level “TRACE **行更改为其他级别然后重新运行该程序查看日志输出的更改情况。 如果你没有写 logback.xml 文件日志系统将采取默认配置。 这只是 SLF4J 最简单的介绍和一般的日志消息但也足以作为使用日志的基础 - 你可以沿着这个进行更长久的学习和实践。你可以查阅 SLF4J 文档来获得更深入的信息。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/91858.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网页设计素材图片黑白电脑优化系统的软件哪个好

java 泛型和类型擦除“编译期间擦除泛型”是常识&#xff08;好吧&#xff0c;类型参数和实参实际上是被擦除的&#xff09;。 这是由于“类型擦除”而发生的。 但这是错误的&#xff0c;正如许多开发人员所假设的那样&#xff0c;将<..>符号内指定的所有内容都删除了。 …

濮阳市网站怎么做宣传推荐做网站的话术

思科设备SSH登陆详细配置过程我们用GNS3进行拓扑搭建。实验拓扑图如下&#xff1a;进行完基本配置之后开始配置SSH服务器(R2)1.首先验证设备是否支持SSHR2#show ip ssh能够识别这条命令就说明支持。2.配置IP域名。使用config# ip domain-name domain-name全局配置模式命令配置网…

网站广告位有哪些网站二级目录怎么做

1. 类 1.1. 简介 TypeScript是面向对象的JavaScript。   类描述了所创建的对象共同的属性与方法。 1.2. 类的定义 class class_name { // 类作用域 }&#xff08;1&#xff09;定义类的关键字是class&#xff0c;后面紧跟类名&#xff0c;类可以包含以下几个模块&#xff…

光明新区城市建设局网站做网站要注册公司吗

1、考虑下列三种情况下&#xff0c;对比一下普通RNN的表现和LSTM和GRU表现&#xff1a; &#xff08;1&#xff09;早期观测值对预测未来观测者具有非常重要的意义。 考虑一个极端情况&#xff0c;其中第一个观测值包含一个校验和&#xff0c; 目标是在序列的末尾辨别校验和是…

自己有网站怎么推广wordpress网站设密码

线程组&#xff08; Threads &#xff08;Users&#xff09;&#xff09;理解&#xff1a;一个虚拟用户组&#xff0c;线程组内线程数量在运行过程中不会发生改变。 注意事项&#xff1a;线程间变量相互独立。 一个测试计划内可以包含多个线程组。 可定义内容&#xff1a; 取样…

建设网站公司浩森宇特深圳在建高铁站

你好&#xff0c;我是 shengjk1&#xff0c;多年大厂经验&#xff0c;努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注&#xff01;你会有如下收益&#xff1a; 了解大厂经验拥有和大厂相匹配的技术等 希望看什么&#xff0c;评论或者私信告诉我&#xff01; 文章目录 一…

金华兰溪网站建设河源正规网站建设价格

codevs 1040 统计单词个数 2001年NOIP全国联赛提高组 题目等级 : 黄金 Gold题目描述 Description给出一个长度不超过200的由小写英文字母组成的字母串(约定;该字串以每行20个字母的方式输入&#xff0c;且保证每行一定为20个)。要求将此字母串分成k份(1<k<40)&#xff0c…

网站建设要如何选择网站宣传推广

目录 1. 切换 Frame 2. 前进后退 3. 对 Cookies 操作 4. 选项卡管理(了解) 5. 异常处理 6. 反屏蔽 7. 无头模式 1. 切换 Frame 我们知道网页中有一种节点叫作 iframe&#xff0c;也就是子 Frame&#xff0c;相当于页面的子页面&#xff0c;它的结构和外部网页的结构完全…

如何用电脑做网站服务器网站后台管理系统地址

1 索引类型 返回面试宝典 主键索引&#xff08;PRIMARY&#xff09;:数据列不允许重复&#xff0c;不允许为NULL&#xff0c;一个表只能有一个主键。 唯一索引&#xff08;UNIQUE&#xff09;:数据列不允许重复&#xff0c;允许为NULL&#xff0c;一个表允许多个列创建唯一索引…

网站地图xml文件济南房产信息网官网

使用sealed关键字声明一个密封类或者接口 sealed interface Errorsealed class IOError(): Error密封类和接口能够很好的控制继承&#xff0c;在密封类和接口定义的模块和包外无法被继承 在编译期我们就已知了所有的密封类和接口的实现类。在某种意义上&#xff0c;密封类类似…

上街做网站微商代理

正题 题目链接:https://www.51nod.com/Contest/Problem.html#contestProblemId1149 题目大意 nnn个数&#xff0c;求有多少种选择方案使选择的数乘机为kkk。 解题思路 显然kkk的质因数最多只有999个&#xff0c;我们将质因数进行dpdpdp。若选择的数的质因数刚好是kkk的质因数…

网站建设越秀爱旅游网站制作

目录 一、Interconnects 1、Crossbars 二、Debugging 官网教程&#xff1a;gem5: Classic caches 默认缓存是一个带有MSHR&#xff08;未命中状态保持寄存器&#xff09;和WB&#xff08;写缓冲区&#xff09;的非阻塞缓存&#xff0c;用于读取和写入未命中。缓存还可以启用…

360怎么做网站搜索家庭电脑做网站

数据采集的方法&#xff1a; 1、API API又叫应用程序接口&#xff0c;是网站的管理者为了使用者方便&#xff0c;编写的一种程序接口。该类接口可以屏蔽网站底层复杂算法仅仅通过简单的调用即可实现对数据请求的功能。目前主流的社交媒体&#xff0c;比如微博、贴吧等均可提供…

怎样为网站设计关键词wordpress配置域名

文章目录 get_domain 返回所有输入图像的定义域作为一个区域add_channels 给区域增加灰度值find_shape_model 发现匹配模板find_shape_models 发现最佳模板示例 get_domain 返回所有输入图像的定义域作为一个区域 Halcon 中的区域 get_domain(Image : Domain : : ) Image : …

网站报价明细表wordpress istax

基于matlab的粒子滤波进行锂离子电池的循环寿命预测&#xff0c;输出实验、粒子滤波及自然预测数据结果。程序已调通&#xff0c;可直接运行。 111matlab锂离子电池寿命预测 (xiaohongshu.com)

黔西南北京网站建设建设通网站是筑龙网的吗

前言 现代社会&#xff0c;技术日新月异&#xff0c;要想跟上技术的更新就必须不断学习&#xff0c;而学习技术最有效方式就是阅读优秀的源码&#xff0c;而优秀的源码都不是简单的逻辑堆积&#xff0c;而是有很灵活的设计模式应用其中&#xff0c;如果我们不懂设计模式&#…

做任务赚佣金的网站网站建设及推广销售话术

为了适应各类复习迎考&#xff0c;大家都会利用一些题目来练习。当面对题目与答案分离的现状(两个文档或一个文档的两个部分)时&#xff0c;怎样将题目和答案合二为一&#xff0c;使答案自动填充到题目后的括号中是颇让大家头疼的一件事情。经过实践探索多步骤的组合操作可以实…

有哪些做微信小游戏的网站自适应网站案例

文章目录 1.打开webpack配置文件2.配置webpack 1.打开webpack配置文件 yarn eject or npm run eject 如果报错了记得提前 git commit一下 2.配置webpack 找到 webpack.config.js 文件在 webpack.config.js 文件中找到 alias 配置在alias里添加: path.resolve(src) , 或者 : pa…

磁县网站设计公司新媒体营销论文

上图是DB-Engines数据库流行度最新排行榜&#xff0c;Oracle、MySQL、SQLServer虽几经下滑&#xff0c;然而还是遥遥领先的前三名。后起之秀PostgreSQL和MongoDB持续增长&#xff0c;然而在体量上还相差甚远&#xff0c;可以预见这些年&#xff0c;三大关系型数据库的主流地位是…

做国外房产的网站用word可以做网站吗

1. 说明 接口注册&#xff0c;使用RequestMappingHandlerMapping来实现mybatis中动态执行sql使用github上的SqlMapper工具类实现 2. 核心代码片段 以下代码为spring动态注册接口代码示例 Autowired private RequestMappingHandlerMapping requestMappingHandlerMapping;publ…