The script does load the new <iframe>. The problem is that the <form> is also submitted (if the browser supports implicit form submission) which then reloads the page with the original <iframe>.
One simple solution is to remove the <form> element. Without a <form> element, there can be no form submission:
<!--form-->
<button onclick="changeIframeSrc()">Click here</button>
<iframe id="myFrame" src="test1.html"></iframe>
<!--/form-->
Another is to prevent the default action of the <button> by returning false from the onclick handler:
<form>
<button onclick="changeIframeSrc(); return false;">Click here</button>
<iframe id="myFrame" src="test1.html"></iframe>
</form>
However, there is a problem with these solutions. If the browser doesn't execute the script, or the script fails in some unanticipated way, the user is left with a dead button. Ideally, the button should submit the form in a useful way when the script doesn't run. Eg.:
<form>
<button name=frame value=2 onclick="changeIframeSrc(); return false;">Click here</button>
<iframe id="myFrame" src="test1.html"></iframe>
</form>
The add some server-side code that outputs the form, but with src="test2.html" as the default <iframe> source if the page is requested with the form data frame=2.