diff --git a/cosmogramme/php/integration/integration_phase.php b/cosmogramme/php/integration/integration_phase.php
index 0b1f6f6daae68c44d1099ac190cc7c3ace1ce4e2..3927cb0326103cdd5cab7b38eb43ce29f86ef810 100644
--- a/cosmogramme/php/integration/integration_phase.php
+++ b/cosmogramme/php/integration/integration_phase.php
@@ -20,7 +20,7 @@
  */
 
 function startIntegrationPhase($name) {
-	global $chrono, $chrono_fichier, $chrono100notices, $phase, $phase_data, $mode_cron, $reprise, $log;
+	global $chrono, $chrono_fichier, $chrono100notices, $phase, $phase_data, $mode_cron, $reprise, $log, $compteur;
 
 	$integration_class_name = 'Class_Cosmogramme_Integration_Phase'.ucfirst($name);
 
@@ -32,7 +32,8 @@ function startIntegrationPhase($name) {
 	$current_phase = Class_Cosmogramme_Integration_Phase::fromLegacyState($phase,
 																																				$phase_data,
 																																				$mode_cron,
-																																				$reprise);
+																																				$reprise,
+																																				$compteur);
 
 
 	$requested_phase = new $integration_class_name($current_phase,
@@ -43,7 +44,7 @@ function startIntegrationPhase($name) {
 
 // reinject state into global scope
 	$current_chrono->backToLegacyState($chrono, $chrono_fichier, $chrono100notices);
-	$new_phase->backToLegacyState($phase, $phase_data, $mode_cron, $reprise);
+	$new_phase->backToLegacyState($phase, $phase_data, $mode_cron, $reprise, $compteur);
 
 
 	if (!$mode_cron && $requested_phase->isTimeOut())
diff --git a/library/Class/Cosmogramme/Integration/Phase.php b/library/Class/Cosmogramme/Integration/Phase.php
index 3e7e9050b2ba2fb30826f2ca7343e1f6900d5aab..a2332c50b446169bb21e968877986ac7ae7ec680 100644
--- a/library/Class/Cosmogramme/Integration/Phase.php
+++ b/library/Class/Cosmogramme/Integration/Phase.php
@@ -22,17 +22,31 @@
 class Class_Cosmogramme_Integration_Phase {
   use Trait_TimeSource;
 
+  const RECORD_REJECT = 0;
+  const RECORD_INSERT = 1;
+  const RECORD_DELETE = 2;
+  const RECORD_FULLUPDATE = 3;
+  const RECORD_UPDATE = 4;
+  const RECORD_RENEW = 5;
+  const RECORD_UPGRADE = 6;
+  const RECORD_SUCCINCT = 7;
+
+
   protected $_id;
   protected $_datas = [];
   protected $_is_callback = false;
   protected $_is_cron = false;
+  protected $_count = [];
 
 
-  public static function fromLegacyState($id, $datas, $is_cron, $is_callback) {
+  public static function fromLegacyState($id, $datas, $is_cron, $is_callback, $compteur) {
     $instance = new Class_Cosmogramme_Integration_Phase($id);
     foreach($datas as $k => $v)
       $instance->setData($k, $v);
 
+    foreach($compteur as $k => $v)
+      $instance->setCount($k, $v);
+
     if ($is_callback)
       $instance->beCallBack();
 
@@ -52,7 +66,7 @@ class Class_Cosmogramme_Integration_Phase {
   }
 
 
-  public function backToLegacyState(&$id, &$datas, &$is_cron, &$is_callback) {
+  public function backToLegacyState(&$id, &$datas, &$is_cron, &$is_callback, &$count) {
     $id = $this->_id;
     $is_cron = $this->isCron();
     $is_callback = $this->isCallBack();
@@ -60,6 +74,10 @@ class Class_Cosmogramme_Integration_Phase {
     $datas = [];
     foreach($this->_datas as $k => $v)
       $datas[$k] = $v;
+
+    $count = [];
+    foreach($this->_count as $k => $v)
+      $count[$k] = $v;
   }
 
 
@@ -90,6 +108,14 @@ class Class_Cosmogramme_Integration_Phase {
   }
 
 
+  public function beSameCountAs($other) {
+    foreach($other->getFullCount() as $k => $v)
+      $this->setCount($k, $v);
+
+    return $this;
+  }
+
+
   public function isCallBack() {
     return $this->_is_callback;
   }
@@ -127,6 +153,31 @@ class Class_Cosmogramme_Integration_Phase {
   }
 
 
+  public function setCount($type, $value) {
+    $this->_count[$type] = $value;
+    return $this;
+  }
+
+
+  public function getCount($type) {
+    return array_key_exists($type, $this->_count) ?
+      $this->_count[$type] : null;
+  }
+
+
+  public function incrementCount($type) {
+    (!array_key_exists($type, $this->_count)) ?
+      $this->_count[$type] = 0 : $this->_count[$type] += 1;
+
+    return $this;
+  }
+
+
+  public function getFullCount() {
+    return $this->_count;
+  }
+
+
   public function resetDatas() {
     $this->_datas = [];
     return $this;
diff --git a/library/Class/Cosmogramme/Integration/PhaseAbstract.php b/library/Class/Cosmogramme/Integration/PhaseAbstract.php
index aea2fb2f2a65b632d4f495d48cd87269936741c2..24de62fd1c341bb66a3dbb21adf53c0974432025 100644
--- a/library/Class/Cosmogramme/Integration/PhaseAbstract.php
+++ b/library/Class/Cosmogramme/Integration/PhaseAbstract.php
@@ -51,7 +51,8 @@ abstract class Class_Cosmogramme_Integration_PhaseAbstract {
       return $this->_phase;
 
     $new_phase = (new Class_Cosmogramme_Integration_Phase(static::MY_ID))
-      ->beSameCronAs($this->_phase);
+      ->beSameCronAs($this->_phase)
+      ->beSameCountAs($this->_phase);
 
     $this->_log->ecrire('<h4>' . $this->_label . '</h4>');
     $this->_init($new_phase);
@@ -97,6 +98,12 @@ abstract class Class_Cosmogramme_Integration_PhaseAbstract {
   }
 
 
+  protected function _incrementCount($name) {
+    $this->_phase->incrementCount($name);
+    return $this;
+  }
+
+
   protected function _printLabel() {
     if (!$this->_phase->isCron() && $this->_wasRunning())
       $this->_getPrinter()->nextPutAll('<h4>' . $this->_label . '</h4>');
diff --git a/library/Class/Cosmogramme/Integration/PhasePseudoRecord.php b/library/Class/Cosmogramme/Integration/PhasePseudoRecord.php
index 4e2e45b9cab962c4989ee06569139aa371b1185d..99139102b968e00cc044c9988b9f38fb247228b0 100644
--- a/library/Class/Cosmogramme/Integration/PhasePseudoRecord.php
+++ b/library/Class/Cosmogramme/Integration/PhasePseudoRecord.php
@@ -21,61 +21,85 @@
 
 
 abstract class Class_Cosmogramme_Integration_PhasePseudoRecord
-	extends Class_Cosmogramme_Integration_PhaseAbstract {
+  extends Class_Cosmogramme_Integration_PhaseAbstract {
 
-	/** @var Trait_Indexable */
-	protected $_model_name;
+  /** @var Trait_Indexable */
+  protected $_model_name;
 
 
-	protected function _getModelIdField() {
-		return call_user_func([$this->_model_name, 'getIdField']);
-	}
+  protected function _getModelIdField() {
+    return call_user_func([$this->_model_name, 'getIdField']);
+  }
 
 
-	protected function _loadPage() {
-		$id_field = $this->_getModelIdField();
-		return call_user_func_array([$this->_model_name, 'findAllBy'],
-																[['where' => $id_field . ' > ' . $this->_getData('pointeur_reprise'),
-																	'order' => $id_field,
-																	'limit' => 100
-																	]]);
-	}
+  protected function _loadPage() {
+    $id_field = $this->_getModelIdField();
+    return call_user_func_array([$this->_model_name, 'findAllBy'],
+                                [['where' => $id_field . ' > ' . $this->_getData('pointeur_reprise'),
+                                  'order' => $id_field,
+                                  'limit' => 100
+                                  ]]);
+  }
 
 
-	protected function _execute() {
-		while ($models = $this->_loadPage()) {
-			foreach($models as $model) {
-				if ($this->isTimeOut())
-					return $this->_phase;
+  protected function _execute() {
+    while ($models = $this->_loadPage()) {
+      if ($this->isTimeOut())
+        return;
 
-				$model->index();
-				$this->_incrementData('nombre');
-				$this->_setData('pointeur_reprise', $model->getId());
+      $this->_runPage($models);
+    }
+  }
 
-/* TODO : trace
-				$record = $article->getNotice();
-				$statut = $record
-					? ['statut' => 1,
-						 'id_notice' => $record->getId(),
-						 'unimarc' => $record->getUnimarc(),
-						 'code_barres' => '',
-						 'facettes' => $record->getFacettes()]
-					: ['statut' => 0, 'id_notice' => 0];
 
-					tracePseudoNotice($ret, $statut); */
-			}
-		}
-	}
+  protected function _runPage($models) {
+    foreach($models as $model) {
+      if ($this->isTimeOut())
+        return;
 
+      $this->_runOne($model);
+    }
+  }
 
-	protected function _init($phase) {
-		$phase
+
+  protected function _runOne($model) {
+    $old_record = $model->getNotice();
+    $model->index();
+    $new_record = $model->getNotice();
+
+    $this->_incrementData('nombre');
+    $this->_setData('pointeur_reprise', $model->getId());
+
+    if (!$old_record && !$new_record)
+      continue;
+
+    if (!$old_record) {
+      $this->_incrementCount(Class_Cosmogramme_Integration_Phase::RECORD_INSERT);
+      return;
+    }
+
+    if (!$new_record) {
+      $this->_incrementCount(Class_Cosmogramme_Integration_Phase::RECORD_DELETE);
+      return;
+    }
+
+    $this->_incrementCount(Class_Cosmogramme_Integration_Phase::RECORD_UPDATE);
+  }
+
+
+  protected function _wasRunning() {
+    return $this->_getData('nombre') > 0;
+  }
+
+
+  protected function _init($phase) {
+    $phase
       ->resetDatas()
-			->setData('pointeur_reprise', 0)
-			->setData('nombre', 0);
+      ->setData('pointeur_reprise', 0)
+      ->setData('nombre', 0);
 
     $this->_chrono
       ->startOnFile()
       ->startOnRecords();
-	}
+  }
 }
\ No newline at end of file
diff --git a/tests/library/Class/Cosmogramme/Integration/PhasePseudoRecordTest.php b/tests/library/Class/Cosmogramme/Integration/PhasePseudoRecordTest.php
index 4f58cfa83fe71eae3edf7a3229005904df6beb18..5c08bd422ae693fab068f3d7aca36aa01d5a93dc 100644
--- a/tests/library/Class/Cosmogramme/Integration/PhasePseudoRecordTest.php
+++ b/tests/library/Class/Cosmogramme/Integration/PhasePseudoRecordTest.php
@@ -20,60 +20,196 @@
  */
 
 
-class PhasePseudoRecordTest extends Class_Cosmogramme_Integration_PhaseTestCase {
-	public function setUp() {
-		parent::setUp();
-		$this->_phase = $this->_buildPhase('PseudoRecordCms')->run();
-	}
+abstract class PhasePseudoRecordCmsTestCase extends Class_Cosmogramme_Integration_PhaseTestCase {
+  public function setUp() {
+    parent::setUp();
+    $this->_phase = $this->_buildPhase('PseudoRecordCms')->run();
+  }
+
+
+  protected function _prepareFixtures() {
+    $art_15 = $this->fixture('Class_Article',
+                             ['id' => 15,
+                              'titre' => 'Article 15',
+                              'contenu' => 'Content 15',
+                              'indexation' => 1]);
+
+    $art_16 = $this->fixture('Class_Article',
+                             ['id' => 16,
+                              'titre' => 'Article 16',
+                              'contenu' => 'Content 16']);
+
+    $this->onLoaderOfModel('Class_Article')
+         ->whenCalled('findAllBy')
+         ->with(['where' => 'id_article > 0',
+                 'order' => 'id_article',
+                 'limit' => 100])
+         ->answers([$art_15])
+
+         ->whenCalled('findAllBy')
+         ->with(['where' => 'id_article > 15',
+                 'order' => 'id_article',
+                 'limit' => 100])
+         ->answers([$art_16])
+
+         ->whenCalled('findAllBy')->answers([]);
+  }
+}
+
+
+
+class PhasePseudoRecordCmsInvalidPreviousPhaseTest extends PhasePseudoRecordCmsTestCase {
+  protected function _getPreviousPhase() {
+    return (new Class_Cosmogramme_Integration_Phase(2))
+      ->beCron();
+  }
 
 
-	protected function _prepareFixtures() {
-		$article = $this->fixture('Class_Article',
-															['id' => 15,
-															 'titre' => 'Un article',
-															 'contenu' => 'Un contenu',
-															 'indexation' => 1]);
+  /** @test */
+  public function recordShouldNotBeCreated() {
+    $this->assertNull(Class_Article::find(15)->getNotice());
+  }
 
-		$this->onLoaderOfModel('Class_Article')
-				 ->whenCalled('findAllBy')
-				 ->with(['where' => 'id_article > 0',
-								 'order' => 'id_article',
-								 'limit' => 100])
-				 ->answers([$article])
 
-				 ->whenCalled('findAllBy')->answers([]);
+  /** @test */
+  public function logShouldNotContainsPhaseLabel() {
+    $this->assertNotLogContains('Pseudo-notices : CMS');
+  }
+}
 
-	}
 
 
+class PhasePseudoRecordCmsValidCronTest extends PhasePseudoRecordCmsTestCase {
   protected function _getPreviousPhase() {
     return (new Class_Cosmogramme_Integration_Phase(0.1))
-			->setData('pointeur_reprise', 45)
-			->beCron();
+      ->setData('pointeur_reprise', 45)
+      ->setCount(Class_Cosmogramme_Integration_Phase::RECORD_INSERT, 5)
+      ->beCron();
+  }
+
+
+  /** @test */
+  public function shouldHaveCreatedArticle15PseudoRecord() {
+    $this->assertNotNull(Class_Article::find(15)->getNotice());
   }
 
 
-	/** @test */
-	public function shouldHaveCreatedPseudoRecord() {
-		$this->assertNotNull(Class_Article::find(15)->getNotice());
-	}
+  /** @test */
+  public function shouldHaveCreatedArticle16PseudoRecord() {
+    $this->assertNotNull(Class_Article::find(16)->getNotice());
+  }
+
+
+  /** @test */
+  public function traitemenPhaseShouldBePseudoRecord() {
+    $this->assertEquals('Pseudo-notices : CMS',
+                        Class_CosmoVar::get('traitement_phase'));
+  }
 
 
-	/** @test */
-	public function traitemenPhaseShouldBePseudoRecord() {
-		$this->assertEquals('Pseudo-notices : CMS',
-												Class_CosmoVar::get('traitement_phase'));
-	}
+  /** @test */
+  public function logShouldContainsPhaseLabel() {
+    $this->assertLogContains('Pseudo-notices : CMS');
+  }
+
+
+  /** @test */
+  public function dataNombreShouldBe2() {
+    $this->assertEquals(2, $this->_phase->getData('nombre'));
+  }
 
 
-	/** @test */
-	public function logShouldContainsPhaseLabel() {
-		$this->assertLogContains('Pseudo-notices : CMS');
-	}
+  /** @test */
+  public function insertCountShouldBe7() {
+    $this->assertEquals(7,
+                        $this->_phase
+                        ->getCount(Class_Cosmogramme_Integration_Phase::RECORD_INSERT));
+  }
 }
 
 
-/** TODO
-		Testcase avec réentrance
-		Testcase avec pagination
-*/
\ No newline at end of file
+
+
+class PhasePseudoRecordCmsValidInteractiveTimeoutTest extends PhasePseudoRecordCmsTestCase {
+  protected function _getPreviousPhase() {
+    return (new Class_Cosmogramme_Integration_Phase(0.1));
+  }
+
+
+  protected function _prepareFixtures() {
+    parent::_prepareFixtures();
+    $this->_time_source = $this
+      ->mock(new Class_TimeSource())
+      ->whenCalled('time')->answers(mktime(1, 0, 0, 9, 1, 2015))
+      ->whenCalled('dateYmd')->answers('2015-09-01');
+
+    Class_Cosmogramme_Chronometre::setTimeSource($this->_time_source);
+    Class_Cosmogramme_Integration_PhasePseudoRecord::setTimeSource($this->_time_source);
+
+    $this->_chrono->start(mktime(0, 0, 0, 9, 1, 2015));
+  }
+
+
+  /** @test */
+  public function shouldNotHaveCreatedRecord() {
+    $this->assertEquals(0, Class_Notice::count());
+  }
+}
+
+
+
+class PhasePseudoRecordCmsValidInteractiveCallbackTest extends PhasePseudoRecordCmsTestCase {
+  protected function _getPreviousPhase() {
+    return (new Class_Cosmogramme_Integration_Phase(0.2))
+      ->beCallBack()
+      ->setData('nombre', 1)
+      ->setData('pointeur_reprise', 15)
+      ->setCount(Class_Cosmogramme_Integration_Phase::RECORD_INSERT, 6);
+  }
+
+
+  protected function _prepareFixtures() {
+    parent::_prepareFixtures();
+    $this->_time_source = $this
+      ->mock(new Class_TimeSource())
+      ->whenCalled('time')->answers(mktime(0, 0, 0, 9, 1, 2015))
+      ->whenCalled('dateYmd')->answers('2015-09-01');
+
+    Class_Cosmogramme_Chronometre::setTimeSource($this->_time_source);
+    Class_Cosmogramme_Integration_PhasePseudoRecord::setTimeSource($this->_time_source);
+
+    $this->_chrono->start(mktime(0, 0, 0, 9, 1, 2015));
+  }
+
+
+  /** @test */
+  public function shouldNotHaveCreatedArticle15PseudoRecord() {
+    $this->assertNull(Class_Article::find(15)->getNotice());
+  }
+
+
+  /** @test */
+  public function shouldHaveCreatedArticle16PseudoRecord() {
+    $this->assertNotNull(Class_Article::find(16)->getNotice());
+  }
+
+
+  /** @test */
+  public function printerShouldContainsPhaseLabel() {
+    $this->assertPrinterContains('Pseudo-notices : CMS');
+  }
+
+
+  /** @test */
+  public function dataNombreShouldBe2() {
+    $this->assertEquals(2, $this->_phase->getData('nombre'));
+  }
+
+
+  /** @test */
+  public function insertCountShouldBe7() {
+    $this->assertEquals(7,
+                        $this->_phase
+                        ->getCount(Class_Cosmogramme_Integration_Phase::RECORD_INSERT));
+  }
+}
\ No newline at end of file
diff --git a/tests/library/Class/Cosmogramme/Integration/PhaseTestCase.php b/tests/library/Class/Cosmogramme/Integration/PhaseTestCase.php
index 213994ea97737bffc17cd889d2555f422678141b..1ec618f382e2039dc585bceeec1493938b93036f 100644
--- a/tests/library/Class/Cosmogramme/Integration/PhaseTestCase.php
+++ b/tests/library/Class/Cosmogramme/Integration/PhaseTestCase.php
@@ -25,9 +25,9 @@ require_once('cosmogramme/php/classes/classe_profil_donnees.php');
 abstract class Class_Cosmogramme_Integration_PhaseTestCase extends ModelTestCase {
   protected
     $_storm_default_to_volatile = true,
-    $_log_content,
+    $_log_content = '',
     $_log,
-    $_printer_content,
+    $_printer_content = '',
     $_printer,
     $_phase;
 
@@ -83,6 +83,11 @@ abstract class Class_Cosmogramme_Integration_PhaseTestCase extends ModelTestCase
   }
 
 
+  protected function assertPrinterContains($value) {
+    $this->assertContains($value, $this->_printer_content);
+  }
+
+
   protected function assertNotLogContains($value) {
     $this->assertNotContains($value, $this->_log_content);
   }