Internationalization (I18n) is everything we do to ensure that products can be localized. This means that products are adapted for use in global markets, with one of the most obvious adaptions being translation. Implementing basic I18n best practices will help you achieve a more flexible source product and one that is ready to go global. If you are a developer externalizing strings should be at the top of your I18n To-Do list, right after Unicode-enabling. If you are a test engineer, you’ll want to focus on pseudo-language testing.
If you are moving from waterfall to agile, be sure you and your team can define how you will ensure that I18n practices are incorporated to all of your iterations. You can create individual stories or include test criteria with stories. In this article, we will describe a particular case in which, we, the localization team, created a set of I18n best practices that were posted on the architecture wiki. We provided training to the agile team members and answered questions during twice-weekly Scrum-of-Scrum meetings as well as on a regular basis throughout the project. The agile team members adopted the practices as doneness criteria for all stories. Over twenty best practices are defined for agile teams in our organization. For this article, we selected just two of them on the basis of prioritization. That is, we believe if you do nothing else, externalizing strings and conducting pseudo-language testing during each iteration and sprint will give you the most payback for the least investment. We’ll tell you about results on our last project at the end of this article.
Externalize All Strings
Words that are embedded in the code cannot be translated to a target language in any sane way. Let’s face it, unless your company has no possibility of ever taking its product global, some manager is going to greet you one day with “Good news! Our product is going to be translated to six languages!” If you’ve hard-coded the UI strings, then what you should really hear in your head is “Tough luck! You have to re-engineer the product—fast!” To avoid the bad news and the subsequent boring and problem-riddled job, just externalize all strings, all the time. In addition to quality-of-life purposes, you have significant usability and business reasons for externalizing strings. As an example, assume that someone translates a product from source English to Simplified Chinese. If even some strings are embedded, here’s what your customer in China might see:
Figure 1. Mock-up of a screen showing what can happen if we do not externalize strings. This graphic does not represent a real screen or real translations.
You may not think it’s a big deal. It’s just a couple of words in English. Right? So let’s try it another way other way around. In this case, someone translates a product from source Chinese to English, strings are embedded, and you get this screen for your personal use:
Figure 2. This image details the same problem as Figure 1.
Point taken? You need to externalize strings; do it for the sake of users, the business, and yourself. By externalizing all strings all the time, you’ll be able to prove on demo days that your product UI is equally current for all supported human languages.
Do Pseudo-Language Testing
You can waste a lot of time finding UI and functional bugs during localization testing when it is usually too late to do anything about fixing them. Or you can swat bugs like flies (pun intended) by setting up and testing with a fake human language in the first place, sprint by sprint. This activity is called pseudo-language testing. It’s pretty easy to do if you already know how to set up an alternative UI language to your source language. And you don’t need to speak any language other than the source to succeed.
Let’s say your source English product is going to be translated into one or more target languages. We’ll stay clear of bi-directional languages for now and assume these target languages are Simplified Chinese, French, and German. Here’s what you do: First, setup for a language pack for Pseudo, just as you would do for French, Spanish, Chinese, and for other languages in the future. Then, programmatically, surround the entire set of English strings with non-English characters. For example, let’s assume you have these two English strings in a text file that contains all of the English UI strings:
Enter your name:
Enter your address:
Select characters from the target languages sets, minimally, to create a Pseudo language that you can read.
In a Pseudo language, for example, our two strings could become:
里îßEnter your name:里îß
里îßEnter your address:里îß
When you view the strings in the context of your running software, with the language set to be Pseudo (or whatever name you chose), you will be able to notice bugs such as:
- Embedded string, because you do not see 里îß at all.
- Insufficient space allowed for the translation, because 里îß is missing in full or in part from one end of the strings and/or because the entire string extends outside the space designed for it.
- Improper use of concatenation to create an English “sentence” from two or more individual strings, because you see something like this: 里îßEnter your里îß里îß里îß address:里îß, in which the string shows the special characters used multiple times and sequentially.
Feel free to include characters from additional languages if you want a more thorough test. Thai characters (เข้าสู่) are usually good if you want to test for potential font type and size issues.
Save yourself a lot of trouble and turn your team members into heroes: use pseudo-language testing as your default practice within the agile team. You will more thoroughly and more globally debug the product during early testing. Better yet, you can, perhaps, increase efficiencies and can prove doneness for all supported languages sprint by sprint. Consider this: for one bug you find during pseudo-language testing, you avoid needing to find that same bug multiple times in all target languages, not to mention avoiding the risk of letting international customers find them unnecessarily. By the time your product is delivered in, say, ten or more languages, those numbers add right up!
In 2013, we experienced measurable success across the board by adopting I18n best practices as story doneness criteria. The teams found and fixed forty I18n/functional bugs during the sprints, preventing those forty from becoming 360 bugs (forty multiplied by nine languages) to find and report during localization testing. In-sprint practices let us produce better products for our international customers who use localized products, too. Because the localization team did not have to focus on those 306 I18n bugs, we could focus instead on finding and fixing localization bugs instead.
Other basic I18n best practices should apply to all your work, including avoiding the use of concatenation techniques to create user-visible strings, allowing for expansion of text, and how to avoid possible coding issues related to the apostrophe mark (‘), and others. But those are topics for another time. We hope that your key take-away from this article is understanding the value of incorporating I18n best practices. like externalizing strings and conducing pseudo-language testing as in-sprint actions. Happy internationalizing!