So, lets say we wanted to modify this code a little. First of course we would write unit tests so we have some confidence we don't break anything along the way. The following code could go in an external test script that uses SoundofMusicSong, but for this example just replace the 1; line at the end of the module with:

sub note_to_sound { my ($note) = @_; return $notes{$note}; } use Test::More tests => 8; return 1 if caller(); # Done if loaded as a module my $song = make_SoM_song (join ' ', 'a' .. 'g'); my @expected = map{note_to_sound($_)} 'a' .. 'g'; Test::More::is_deeply($song, \@expected, "Notes map correctly to phras +es"); my %noteCounts; my $samples = 100000; my $nominal = $samples / 7; ++$noteCounts{random_SoM_note($_)} for 1 .. $samples; Test::More::ok (abs($noteCounts{$_} - $nominal) < 200, "Random distrib +ution of $_: $noteCounts{$_}") for map {note_to_sound($_)} 'a' .. 'g';

note_to_sound was added to the module to facilitate testing - it avoids having to access %notes directly. Now lets rework the code a little:

package SoundOfMusicSong; use strict; use warnings; my %SoM = ( 'c' => {phrase => 'a deer a female deer', sound => 'do'}, 'd' => {phrase => 'a drop of golden sun', sound => 're'}, 'e' => {phrase => 'a name I call myself', sound => 'me'}, 'f' => {phrase => 'a long long way to run', sound => 'fa'}, 'g' => {phrase => 'a needle pulling thread', sound => 'so'}, 'a' => {phrase => 'a note to follow so', sound => 'la'}, 'b' => {phrase => 'a drink with jam and bread', sound => 'te'}, ); my @notes = keys %SoM; sub make_SoM_song { my ($user_song) = @_; return [ map {exists $SoM{$_} ? $SoM{$_}->{sound} : 'not a note'} split /\W+/, $user_song ]; } sub getPhrase { my ($user_song) = @_; my $notes = make_SoM_song($user_song); my @new_song = map {$SoM{$_} ? "$_ $SoM{$_}" : 'not a note'} @$not +es; return \@new_song; } sub random_SoM_note { return $SoM{$notes[rand @notes]}{sound}; } sub random_SoM_song { my ($number_of_notes) = @_; $number_of_notes ||= int(rand(100)) + 1; return [map {random_SoM_note()} 1 .. $number_of_notes]; } sub note_to_sound { my ($note) = @_; return $SoM{$note}{sound}; }

Now we have, for better or worse, a major overhaul of the module, but when we run the unit tests they still all pass so the reworked code is good to go.

The test suite doesn't test the entire interface provided by the module so the test suite is incomplete and maybe we've introduced badness in the untested areas? If we are really serious about unit testing we would run code coverage tools (see Devel::Cover) in conjunction with the unit tests to ensure all the code we care about is tested.

Perl is the programming world's equivalent of English

In reply to Re: The hills are alive... by GrandFather
in thread The hills are alive... by Lady_Aleena

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.