Java中连字符显示为问号导致equals断言失败的解决方法
问题原因
这个问题核心是字符编码不一致:
你代码里写的−不是普通ASCII半角连字符-,是Unicode编号为U+2212的数学减号字符。控制台把它显示成?,是因为当前控制台默认字符集(常见的是GBK、ISO-8859-1)不支持这个字符,会自动把无法识别的字符替换为问号。你报错信息里expected字符串末尾多出来的S,也是编码转换错误衍生的乱码。
另外Selenium的getText()方法会直接拿到页面渲染的原始Unicode字符,只要你的硬编码字符串、源码文件、JVM运行时、控制台的编码有一环不匹配,就会出现内存中实际字符不一致、断言失败的问题。注意:控制台显示的内容不代表JVM内存里字符串的真实值,不要被控制台的问号输出误导。
可落地的解决方法
按优先级选就行:
- 全链路统一UTF-8编码,从根源解决问题
给JVM加启动参数强制使用UTF-8编码:
如果你是用Maven/Gradle跑自动化测试,记得把测试插件(比如Surefire)的编码配置也设为UTF-8;同时在IDE里把项目源码编码、控制台输出编码全部改成UTF-8,避免任何一环做编码转换时丢字符。-Dfile.encoding=UTF-8 - 用Unicode转义写硬编码字符串,绕开源码编码依赖
如果你暂时没法改全局编码配置,就不要直接在代码里敲特殊字符,用Unicode转义序列写,同时对两边待比对的字符串做相同的归一化处理:// \u2212 就是那个特殊减号的转义写法,不受源码文件编码影响 String expected = "Some usefull information \u2212 don't know what happens with my output"; String actual = driver.findElement(By.xpath("//someWellFormXpath")).getText(); // 也可以根据需要把特殊减号统一替换成普通ASCII连字符再比对 // expected = expected.replace("\u2212", "-"); // actual = actual.replace("\u2212", "-"); Assert.assertEquals(actual, expected); - 排查源码文件本身的编码问题
检查你的.java源码文件是不是被错误保存成了非UTF-8编码(比如ANSI、GBK),导致编译器读取源码时就把特殊字符识别错了,把所有源码文件转存为UTF-8编码后重新编译运行即可。
排查的时候可以把两个待比对字符串的每个字符转成Unicode码点打印,直接看内存里的真实字符值,比盯着控制台输出排查效率高很多。
内容的提问来源于stack exchange,提问作者cagoscra
相关产品推荐
相关产品推荐

