Testing "all" DFAs up to n states and m alphabet symbols is infeasible. You could test DFAs with known minimal DFAs; to get (DFA, minimal DFA) pairs, you could generate random REs, get the NFA-lambda usin the algorithm from Kleene's theorem, get a DFA using the subset construction, then minimize with a known correct algorithm for DFA minimization (I assume you accept that the canonical algorithm is correct).
EDIT:
To expand on what I said, here's how I would try to generate a test suite of non-minimal finite automata:
- Generate a regular expression using N operations (concatenation, union, Kleene closure).
- Use the algorithm from Kleene's theorem to get a NFA-lambda with O(n) states in it.
- Use the subset/powerset construction to get a DFA with O(2^n) states in it.
- Repeat until you have found a sufficient number of sufficiently complex automata.
Generating the regular expressions is easier. There are a few rules:
- a is an RE if a is an alphabet symbol
- (rs) is an RE if r, s are REs
- (r+s) is an RE if r, s are REs
- (r*) is an RE if r is an RE
- Nothing else is an RE
To get an RE with n operations, a recursive approach works.
GetRE(ops)
1. if ops = 0 then return RandomAlphabetSymbol()
2. select(Rand() % 3)
3. case 0 then
4. ops1 = Rand() % (ops - 1)
5. ops2 = (ops - 1) - ops1
6. return "(" + GetRE(ops1) + "+" + GetRE(ops2) + ")"
7. case 1 then
8. ops1 = Rand() % (ops - 1)
9. ops2 = (ops - 1) - ops1
10. return "(" + GetRE(ops1) + "." + GetRE(ops2) + ")"
11. case 2 then
12. return "(" + GetRE(ops - 1) + "*)"
You might find a non-string representation (I.e., a hierarchical linked structure, essentially the parse tree itself) is a more convenient option for applying Kleene's algorithm to get the NFA-lambda.