}
 }
 
-func TestAppendFloatDoesntAllocate(t *testing.T) {
-       n := numAllocations(func() {
-               var buf [64]byte
-               AppendFloat(buf[:0], 1.23, 'g', 5, 64)
-       })
-       want := 1 // TODO(bradfitz): this might be 0, once escape analysis is better
-       if n != want {
-               t.Errorf("with local buffer, did %d allocations, want %d", n, want)
-       }
-       n = numAllocations(func() {
-               AppendFloat(globalBuf[:0], 1.23, 'g', 5, 64)
-       })
-       if n != 0 {
-               t.Errorf("with reused buffer, did %d allocations, want 0", n)
-       }
-}
-
 func BenchmarkFormatFloatDecimal(b *testing.B) {
        for i := 0; i < b.N; i++ {
                FormatFloat(33909, 'g', -1, 64)
 
 package strconv_test
 
 import (
-       "runtime"
        . "strconv"
        "testing"
 )
        }
 }
 
-func numAllocations(f func()) int {
-       runtime.GC()
-       memstats := new(runtime.MemStats)
-       runtime.ReadMemStats(memstats)
-       n0 := memstats.Mallocs
-       f()
-       runtime.ReadMemStats(memstats)
-       return int(memstats.Mallocs - n0)
-}
-
-var globalBuf [64]byte
-
-func TestAppendUintDoesntAllocate(t *testing.T) {
-       n := numAllocations(func() {
-               var buf [64]byte
-               AppendInt(buf[:0], 123, 10)
-       })
-       want := 1 // TODO(bradfitz): this might be 0, once escape analysis is better
-       if n != want {
-               t.Errorf("with local buffer, did %d allocations, want %d", n, want)
-       }
-       n = numAllocations(func() {
-               AppendInt(globalBuf[:0], 123, 10)
-       })
-       if n != 0 {
-               t.Errorf("with reused buffer, did %d allocations, want 0", n)
-       }
-}
-
 func BenchmarkFormatInt(b *testing.B) {
        for i := 0; i < b.N; i++ {
                for _, test := range itob64tests {
 
--- /dev/null
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package strconv_test
+
+import (
+       "runtime"
+       . "strconv"
+       "testing"
+)
+
+var (
+       globalBuf [64]byte
+
+       mallocTest = []struct {
+               count int
+               desc  string
+               fn    func()
+       }{
+               // TODO(bradfitz): this might be 0, once escape analysis is better
+               {1, `AppendInt(localBuf[:0], 123, 10)`, func() {
+                       var localBuf [64]byte
+                       AppendInt(localBuf[:0], 123, 10)
+               }},
+               {0, `AppendInt(globalBuf[:0], 123, 10)`, func() { AppendInt(globalBuf[:0], 123, 10) }},
+               // TODO(bradfitz): this might be 0, once escape analysis is better
+               {1, `AppendFloat(localBuf[:0], 1.23, 'g', 5, 64)`, func() {
+                       var localBuf [64]byte
+                       AppendFloat(localBuf[:0], 1.23, 'g', 5, 64)
+               }},
+               {0, `AppendFloat(globalBuf[:0], 1.23, 'g', 5, 64)`, func() { AppendFloat(globalBuf[:0], 1.23, 'g', 5, 64) }},
+       }
+)
+
+func TestCountMallocs(t *testing.T) {
+       for _, mt := range mallocTest {
+               const N = 100
+               memstats := new(runtime.MemStats)
+               runtime.ReadMemStats(memstats)
+               mallocs := 0 - memstats.Mallocs
+               for i := 0; i < N; i++ {
+                       mt.fn()
+               }
+               runtime.ReadMemStats(memstats)
+               mallocs += memstats.Mallocs
+               if mallocs/N > uint64(mt.count) {
+                       t.Errorf("%s: expected %d mallocs, got %d", mt.desc, mt.count, mallocs/N)
+               }
+       }
+}