Welche Strategien zur Sicherstellung aller länderspezifischen Operationen werden in allen Ländereinstellungen korrekt gehandhabt?

9

Etwas aus der Not heraus entwickelte ich Software mit meinem Gebietsschema, das auf "C" oder "en_US" eingestellt ist. Es ist schwierig, ein anderes Gebietsschema zu verwenden, weil ich nur eine Sprache mit etwas sprechen kann, das sogar flüssig ist.

Infolgedessen übersehe ich oft die Unterschiede im Verhalten, die durch unterschiedliche Gebietsschema-Einstellungen eingeführt werden können. Überraschenderweise führt das Übersehen dieser Unterschiede manchmal zu Fehlern, die nur von einem unglücklichen Benutzer entdeckt werden, der ein anderes Gebietsschema verwendet. In besonders schlimmen Fällen kann dieser Benutzer nicht einmal eine Sprache mit mir teilen, was die Fehlerberichterstattung zu einer schwierigen Aufgabe macht. Und, wichtig , viele meiner Software sind in Form von Bibliotheken; Während fast keiner davon das Gebietsschema festlegt, kann es mit einer anderen Bibliothek kombiniert oder in einer Anwendung verwendet werden, die das Locale - generierende Verhalten, das ich selbst nie erlebe, mit festlegt.

Um etwas genauer zu sein, die Arten von Fehlern, die ich im Sinn habe, fehlen nicht Textlokalisierungen oder Fehler im Code für die Verwendung dieser Lokalisierungen. Stattdessen meine ich Bugs, bei denen ein Gebietsschema das Ergebnis einer lokalen API (z. B. toupper(3) ) ändert, wenn der Code, der diese API verwendet, die Möglichkeit einer solchen Änderung nicht vorausgesehen hat (z. B. im türkischen Gebietsschema% co_de) % ändert nicht "i" in "I" - möglicherweise ein Problem für einen Netzwerkserver, der versucht, ein bestimmtes Netzwerkprotokoll mit einem anderen Host zu sprechen.

Ein paar Beispiele für solche Fehler in der Software, die ich pflege:

In der Vergangenheit habe ich einen Ansatz verfolgt, um Regressionstests zu schreiben, die das Gebietsschema explizit in einen Bereich ändern, in dem der Code bekanntermaßen nicht funktioniert, den Code ausübt, das korrekte Verhalten überprüft und dann das Original wiederherstellt Gebietsschema. Dies funktioniert gut genug, aber nur, nachdem jemand einen Fehler gemeldet hat, und es deckt nur einen kleinen Bereich einer Codebasis ab.

Ein anderer Ansatz, der möglich scheint, besteht darin, ein Continuous Integration System (CIS) einzurichten, um eine ganze Reihe von Tests in einer Umgebung mit einem anderen Gebietsschema auszuführen. Dies verbessert die Situation ein wenig, indem in dem einen alternativen Gebietsschema, wie es die Testsuite normalerweise gibt, so viel Deckung gegeben wird. Ein weiterer Mangel besteht darin, dass es viele, viele, viele Gebietsschemata gibt, die möglicherweise unterschiedliche Probleme verursachen. In der Praxis gibt es wahrscheinlich nur ein Dutzend verschiedener Arten, wie ein Gebietsschema ein Programm durchbrechen kann, aber Dutzende von zusätzlichen Testkonfigurationen belasten die Ressourcen (insbesondere für ein Projekt, das seine Ressourcengrenzen durch Testen auf verschiedenen Plattformen gegen verschiedene Bibliotheken erweitert) Versionen usw.).

Ein anderer Ansatz, der mir einfällt, ist, ein neues Gebietsschema zu verwenden (möglicherweise zuerst zu erstellen), das sich radikal von dem Gebietsschema "C" unterscheidet - eine andere Fallzuordnung verwenden, ein anderes Tausendertrennzeichen verwenden Datumsangaben anders, usw. Dieses Gebietsschema könnte mit einer zusätzlichen CIS-Konfiguration verwendet werden und hofft hoffentlich darauf, alle Fehler im Code zu erfassen, die von einem Gebietsschema ausgelöst werden könnten.

Existiert ein solches Testgebietsschema bereits? Gibt es Fehler bei dieser Idee, um die Kompatibilität der Ländereinstellungen zu testen?

Welche anderen Ansätze zum Testen von Locale haben Leute genommen?

Ich bin hauptsächlich an POSIX-Gebietsschemas interessiert, da diese mir bekannt sind. Ich weiß jedoch, dass Windows auch einige ähnliche Funktionen hat, daher könnten zusätzliche Informationen (vielleicht mit mehr Hintergrundinformationen darüber, wie diese Funktionen funktionieren), vielleicht auch nützlich sein.

    
Jean-Paul Calderone 28.02.2012, 15:13
quelle

2 Antworten

3

Ich würde Ihren Code nur auf inkorrekte Verwendung von Funktionen wie toupper prüfen. Unter dem C-Gebietsschema-Modell sollten solche Funktionen so betrachtet werden, als ob sie nur in natürlichsprachlichem Text in der Sprache des Gebietsschemas arbeiten. Für jede Anwendung, die sich mit potenziell mehrsprachigem Text befasst, bedeutet dies, dass Funktionen wie tolower überhaupt nicht verwendet werden sollten .

Wenn Ihr Ziel POSIX ist, haben Sie ein wenig mehr Flexibilität aufgrund der Funktion uselocale , die es ermöglicht, das Gebietsschema in einem einzelnen Thread vorübergehend zu überschreiben (d. h. ohne den globalen Status Ihres Programms zu verpfuschen). Sie könnten dann das C-Gebietsschema global beibehalten und% tolower usw. für ASCII / maschinenorientierten Text (wie Konfigurationsdateien usw.) und nur uselocale für das ausgewählte Gebietsschema des Benutzers verwenden, wenn Sie mit natürlichem Text aus diesem Gebietsschema arbeiten.

Sonst (und vielleicht sogar dann, wenn Sie etwas fortgeschrittener sind), denke ich, ist die beste Lösung, Funktionen wie tolower komplett zu verworfen und Ihre eigenen ASCII-Versionen für Config-Text und dergleichen zu schreiben und einen mächtigen Unicode zu verwenden -aware-Bibliothek für natürlichsprachigen Text.

Ein Problem, das ich noch nicht erwähnt habe, ist das Dezimaltrennzeichen in Bezug auf Funktionen wie snprintf und strtod . Wenn sie in einigen Gebietsschemas in , anstelle von . geändert wurde, kann dies die Fähigkeit zum Parsen von Dateien mit der C-Bibliothek ruinieren. Meine bevorzugte Lösung besteht einfach darin, niemals das Gebietsschema LC_NUMERIC einzustellen. (Und ich bin ein Mathematiker, also neige ich dazu zu glauben, dass Zahlen universell sein sollten und nicht kulturellen Konventionen unterliegen.) Abhängig von Ihrer Anwendung können die einzigen wirklich benötigten Gebietsschema-Kategorien nur LC_CTYPE , LC_COLLATE und LC_MESSAGES sein. . Nützlich sind auch LC_MONETARY und LC_TIME .

    
R.. 28.02.2012 16:05
quelle
2

Sie müssen zwei verschiedene Probleme lösen, um Ihre Frage zu beantworten: Testen Ihres Codes und Umgang mit Problemen mit Code anderer Leute.

Testen Ihres eigenen Codes - Ich habe mich damit beschäftigt, indem ich 2 oder 3 englischsprachige Gebietsschemas in einer CI-Umgebung verwende: en_GB (Kollatierung), en_ZW (fast alles ändert sich, aber Sie können immer noch die Fehler lesen) und dann en_AU ( Datum, Sortierung)

Wenn Sie sicherstellen möchten, dass Ihr Code mit Multibyte-Dateinamen arbeitet, müssen Sie auch mit ja_JP

testen

Der Umgang mit Code anderer Leute ist in vielerlei Hinsicht der schwierigste und meine Lösung dafür ist das Speichern der Datumswerte (es sind fast immer Daten :) in ihrem rohen Datum / Zeit Wert und immer behalten sie als GMT. Wenn Sie dann die Grenze Ihrer App überschreiten, konvertieren Sie in das entsprechende Format.

PyTZ und PyICU sind sehr hilfreich dabei.

    
bear 28.02.2012 16:10
quelle