input: Write a python function to implement a MinHeap class with push, pop, and decreaseKey methods. 
  assert minheap_test() == [1, 5, 10, 20]
  assert minheap_test() == [3, 7, 15]
  assert minheap_test() == [2, 8, 12]
output: import heapq
  
  class MinHeap:
      def __init__(self):
          self.heap = []
          self.entry_finder = {}  # mapping of items to their heap entries
          self.REMOVED = '<removed-item>'  # placeholder for a removed item
  
      def push(self, item):
          if item in self.entry_finder:
              self.decreaseKey(item, item)
          else:
              entry = [item, item]
              self.entry_finder[item] = entry
              heapq.heappush(self.heap, entry)
  
      def pop(self):
          while self.heap:
              item, entry = heapq.heappop(self.heap)
              if entry is not self.REMOVED:
                  del self.entry_finder[item]
                  return item
          raise KeyError('pop from an empty priority queue')
  
      def decreaseKey(self, item, new_item):
          if item not in self.entry_finder:
              raise KeyError(f'Item {item} not found in the heap')
          entry = self.entry_finder.pop(item)
          entry[-1] = self.REMOVED
          self.push(new_item)
  
  def minheap_test():
      h = MinHeap()
      h.push(10)
      h.push(20)
      h.push(5)
      h.push(1)
      return [h.pop(), h.pop(), h.pop(), h.pop()]
  
  assert minheap_test() == [1, 5, 10, 20]
  
  def minheap_test():
      h = MinHeap()
      h.push(15)
      h.push(3)
      h.push(7)
      return [h.pop(), h.pop(), h.pop()]
  
  assert minheap_test() == [3, 7, 15]
  
  def minheap_test():
      h = MinHeap()
      h.push(12)
      h.push(8)
      h.push(2)
      return [h.pop(), h.pop(), h.pop()]
  
  assert minheap_test() == [2, 8, 12]