Jea*_*one 9 c python testing locale unit-testing
有点出于必要,我开发的软件的语言环境设置为"C"或"en_US".使用不同的语言环境很困难,因为我只会说一种语言甚至远程接近流利.
因此,我经常忽略通过使用不同的区域设置可以引入的行为差异.不出所料,忽略这些差异有时会导致错误,这些错误只能由一些使用不同区域设置的不幸用户发现.在特别糟糕的情况下,该用户甚至可能不会与我共享语言,使得错误报告过程变得具有挑战性.而且,重要的是,我的很多软件都是图书馆的形式; 而几乎没有它设置了语言环境,它可能与另一个库相结合,或在其应用程序中使用不设置语言环境-产生的行为我从来没有体验自己.
更具体一点,我想到的错误种类并不缺少使用这些本地化的代码中的文本本地化或错误.相反,我的意思是toupper(3)当使用该API的代码没有预料到这种改变的可能性时(例如,在土耳其语语言环境中,toupper不会改变"i ),语言环境会改变某些语言环境感知API(例如)的结果的错误"to"I" - 尝试将特定网络协议讲到另一台主机的网络服务器可能存在问题.
我维护的软件中有一些这样的错误示例:
在过去,我采用的一种处理方法是编写回归测试,明确地将语言环境更改为已知代码无法工作的语言环境,运行代码,验证正确的行为,然后还原原始语言环境.这种方法效果很好,但只有在有人报告了错误之后,它才会覆盖代码库的一小块区域.
另一种似乎可行的方法是建立一个持续集成系统(CIS),以便在具有不同语言环境集的环境中运行一整套测试.通过在测试套件通常给出的一个备用区域设置中提供尽可能多的覆盖,这在一定程度上改善了这种情况.另一个缺点是存在许多很多很多区域设置,并且每个区域设置都可能导致不同的问题.在实践中,区域设置可能只有十几种不同的方式可以破坏程序,但是有几十种额外的测试配置会对资源造成负担(特别是对于已经通过在不同平台上测试,针对不同库来扩展其资源限制的项目版本等).
我想到的另一种方法是使用(可能首先创建)一个新的语言环境,它在各种方式上与"C"语言环境完全不同 - 具有不同的大小写映射,使用不同的千位分隔符,格式化日期不同,此区域设置可以与一个额外的CIS配置一起使用,并希望可以依赖于捕获可由任何区域设置触发的代码中的任何错误.
这样的测试区域是否已经存在?这个想法是否存在缺陷以测试区域设置兼容性?
人们采取了哪些其他的区域测试方法?
我主要对POSIX语言环境感兴趣,因为那些是我所知道的.但是,我知道Windows也有一些类似的功能,因此额外的信息(可能包含有关这些功能如何工作的更多背景信息)也许也很有用.
我只会审核您的代码是否错误地使用了toupper. 在 C 语言环境模型下,此类函数应被视为仅对语言环境语言的自然语言文本进行操作。对于任何处理潜在多语言文本的应用程序,这意味着tolower 根本不应该使用诸如 之类的功能。
如果您的目标是 POSIX,那么您将拥有更多的灵活性,因为该uselocale函数可以在单个线程中临时覆盖区域设置(即不会弄乱程序的全局状态)。然后,您可以全局保留 C 语言环境,并将tolower等用于 ASCII/面向机器的文本(如配置文件等),并且uselocale在处理来自所述语言环境的自然语言文本时仅适用于用户选择的语言环境。
否则(也许即使如此,如果您需要更高级),我认为最好的解决方案是完全抛弃类似的函数,tolower并为配置文本等编写您自己的 ASCII 版本,并使用强大的 Unicode 感知库来实现自然-语言文本。
我尚未触及的一个棘手问题是与snprintf和等函数相关的小数分隔符strtod。在某些语言环境中将其更改为 a,而不是 a.可能会破坏您使用 C 库解析文件的能力。我首选的解决方案就是永远不要设置LC_NUMERIC任何区域设置。(我是一名数学家,所以我倾向于认为数字应该是通用的,不受文化习俗的约束。)根据您的应用程序,真正需要的唯一区域设置类别可能只是LC_CTYPE、LC_COLLATE和LC_MESSAGES。也经常有用的是LC_MONETARY和LC_TIME。