Nested loop called with shortcode duplicating the content above the main loop

You have few errors in your code. Below you can see how it should look like:

function cd_random_testimonial($atts) {

    // EXAMPLE USAGE:
    // [loop the_query="showposts=1&post_type=testimonials&orderby=rand"]

    // Defaults
    extract(shortcode_atts(array(
        'the_query' => ''
        ), $atts));

    // de-funkify query
    $the_query = preg_replace('~&#x0*([0-9a-f]+);~ei', 'chr(hexdec("\\1"))', $the_query);
    $the_query = preg_replace('~&#0*([0-9]+);~e', 'chr(\\1)', $the_query);

    // query is made
    $my_query = new WP_Query( $the_query );  // use custom WP_Query instead of query_posts

    // Reset and setup variables
    $output="";

    // the loop
    if ( $my_query->have_posts() ) {
        while ( $my_query->have_posts() ) {
            $my_query->the_post();

            // the_content outputs content and you want to return it; and it doesn't take post_id as argument... and you don't use this variable, so you can delete this line, I guess
            // $testimonial = get_the_content();  
            $clientname = get_the_title(); // it doesn't take post_id as argument

            // output all findings - CUSTOMIZE TO YOUR LIKING
            $output .= '<blockquote><p class="quote">';
            $output .= get_the_content();  // doesn't take argument
            $output .= '</p><p class="right">~ ';
            $output .= $clientname;
            $output .= '</p></blockquote>';
        }
    } else {
        $output="nothing found.";
    }
    wp_reset_postdata();
    return $output;
}
add_shortcode("loop", "cd_random_testimonial");