|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
Note: This is an unedited contribution. If this article is inappropriate,
needs attention or copies someone else's work without reference then please
Report This Article
The Case for “PhraseFixture”BackgroundThis articles assumes knowledge of FIT (Framework for Integrated Test), and the FitLibrary. OverviewFor those who’ve used DoFixture from FitLibrary, are probably familiar with the ChatStart example (FitLibraryUserGuide.DoFixture.WritingFixtures). Shw here:
What DoFixture attempts to do is to make the table data be more readable. For instance, in the above table, the last row is attempting to be as close as possible to what one would say the phrase in English: “User Sarah enters fit room”. There are two problems here:
public class ChatStart : DoFixture { private ChatRoom chat = new ChatRoom(); public ChatStart() { setSystemUnderTest(chat); } public bool ConnectUser(string userName) { return chat.connectUser(userName); } public bool UserCreatesRoom(string userName, string roomName) { return chat.userCreatesRoom(userName, roomName); } public bool UserEntersRoom(string userName, string roomName) { return chat.userEntersRoom(userName, roomName); } } Proposal: PhraseFixture()It’s possible to have a fixture be smart enough to locate the right method even if the words in the phrase did not follow the column alternating sequence. Furthermore, if spaces were used as the delimiter, then the rows would look a lot better. Example:
Which certainly looks better than:
…and probably easier for the business analyst to type into a table. They way this can be made to work is simply by trying the combinations of words until a matching method is found, and the unused words become the parameters. So for the fourth row, the words “User”, “Enters” and “Room” get matched to the method UserCreatesRoom(), and the unused words, “Sarah” and “fit” end as the parameters to the method. DownsidesEvery solution has it’s set of problems. Although this reads better than DoFixture, since spaces are used as word delimiters, string parameters that contain spaces will have to be dealt with another way. The proposal is to require is to place strings in quotes. So, for instance, if the user name above was “sarah connor” instead of “sarah”, then the author would have to have entered:
which isn’t so bad. AlgorithmThe algorithm is quite simple, and perhaps can be improved. But what it does is like so. As a simpler example, let’s say that the words in the phrase are “Connect user sarah”. It will look for the following method names, and the order ensures that the longest possible name is looked for first:
(The one in bold is obviously the one that will be found since that method exists in the fixture. And since the word “Sarah” is not used in that particular match, that word becomes the parameter to the ConnectUser() function.) I’m sure it’s possible to come up with a smarter algorithm, but the one included here serves the purpose of demonstrating what is possible. Supporting Code
const int cBitsInInt = 32; static uint ReverseBits(uint x) { uint h = 0; uint i = 0; for (h = i = 0; i < cBitsInInt; i++) { h = (h << 1) + (x & 1); x >>= 1; } return (uint)h; } static uint ReverseAndShift(uint x, int length) { return ReverseBits(x) >> (cBitsInInt - length); } static bool FindMethod(MethodInfo[] methods, string[] columns, out MethodInfo foundMethod, out List<string> parameters) { uint bits = (uint)(1 << columns.Length); for (uint i = bits - 1; i >= 0 && i <= cBitsInInt; i--) { string s = ""; parameters = new List<string>(); uint x = ReverseAndShift(i, columns.Length); for (int j = 0; j < columns.Length; j++) { if ((1 & x) > 0) s += columns[j].ToLowerInvariant(); else parameters.Add(columns[j]); x >>= 1; } foreach (MethodInfo method in methods) { if (method.Name.ToLowerInvariant() == s) { foundMethod = method; return true; } } } foundMethod = null; parameters = null; return false; }
Kenneth Kasajian (ken@kasajian.com)
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||