Use Your Users' Viewpoint
As soon as you have even a vague idea about what your feature is all about you can start defining your Logical Functional Model. Ideally your entire feature team will take part in this exercise, but you can certainly do it on your own as well. Ask yourself "What are the user features here?" Don't think about UI or implementation but rather try to see your app through the user's eyes.
For example, I see the user actions in Surveyor as:
- Start and stop the app
- Select an answer for the current question
- Clear the selected answer for the current question
- Move to the next or previous question
- Indicate that the user is done with the survey
- Skip the current question
- Switch between the various question navigation sets
Additional user actions may become available after the user completes the survey, but as Surveyor itself is not concerned with that its LFM won't cover any of the myriad possibilities.
Next organize these actions however makes sense to you and your feature team. This organization is mostly just an aid to navigating the LFM, but if you group things similarly to how your users might your LFM will be more intuitive. For example:
- Application
- Start and stop the app
- Navigation
- Switch between the various question navigation sets
- Move to the next or previous question
- Indicate that the user is done with the survey
- Question
- Select an answer for the current question
- Clear the selected answer for the current question
- Skip the current question
Next convert this to code:
public static class Logical
{
public static class Application
{
public static void Close() { }
}
public static class Navigation
{
public static void SwitchToNotYetAnsweredQuestions() { }
public static void SwitchToSkippedQuestions() { }
public static void SwitchToAnsweredQuestions() { }
public static void MoveToNextQuestion() { }
public static void MoveToPreviousQuestion() { }
public static void IndicateAmDone() { }
}
public static class Question
{
public static void SelectAnswer() { }
public static void ClearAnswer() { }
public static void SkipQuestion() { }
}
}
I used nested classes as a navigation aid, and static classes because you only act on the "active" item (e.g., the current question or the current application), but these are minor implementation details. More important is:
- The active voice used to name the methods, which directly describe the actions your user will take.
- Each method's implied target of the active item.
Although these are somewhat orthogonal as well - the main point is to embed a user action-focused point of view into your LFM.
This is all you need to write test cases!
[TestMethod("TestMethodSetup", "TestMethodTeardown")]
public void CanSwitchBetweenAllQuestionSetsAfterAnsweringAllQuestions()
{
this.AnswerAllQuestions();
this.SwitchBetweenAllQuestionSets();
}
private void AnswerAllQuestions()
{
this.MoveToFirstQuestion();
do
{
Logical.Question.SelectAnswer(this.SurveyNavigator.CurrentQuestion.PossibleAnswers[1].Label);
Logical.Navigation.MoveToNextQuestion();
} while (this.SurveyNavigator.ThereIsANextQuestion());
}
private void SwitchBetweenAllQuestionSets()
{
Logical.Navigation.SwitchToAnsweredQuestions();
Logical.Navigation.SwitchToSkippedQuestions();
Logical.Navigation.SwitchToNotYetAnsweredQuestions();
}
You can't actually run the test cases of course (well, not and have them actually do anything anyway), but they will compile. They don't contain any verification or UI or other implementation details, so you won't have to edit your test cases as those details change. The intent of each test is immediately clear - you don't have to hack through thickets of UI manipulation, application internal data structure accesses, and verification code to figure out what their points are. It is quite likely that once your LFM methods are filled out and the application under test implements the corresponding functionality your test cases will just "light up" and start working. The only reason you should need to modify a test case, in fact, is if the user feature it is testing radically changes! If the feature is cut or given completely different semantics than you will need to revisit test cases, but simply changing how the UI works or adding a new way to execute the action generally won't have any repercussions on your existing test cases.
*** Comments, questions, feedback? Let's talk: michhu at microsoft dot com.
Comments
- Anonymous
June 29, 2005
Once you create your Logical Functional Model the other pieces can follow in any order immediately as... - Anonymous
July 06, 2005
The comment has been removed - Anonymous
July 20, 2005
Your Logical Functional Model lets you write test cases from your user's point of view, test cases that... - Anonymous
July 23, 2005
Ive recently been reading an article about how to de-couple the various sections of a test case.  I love the idea of being able to write test usable test cases from the very onset of a feature. This framework seems very flexible and usable but for me the - Anonymous
July 27, 2005
Jerrad is writing a Logical Functional Model for a website. He is approaching the problem exactly... - Anonymous
August 03, 2005
In many of my posts I have alluded to the automation stack my team is building, but I have not provided...